From b4bb75d6ad34e8097371d330f76458fc3a005384 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 21 Mar 2018 17:23:32 +0000 Subject: [PATCH] [Hexagon] Generalize DAG mutation for function calls Add barrier edges to check for any physical register. The previous code worked for the function return registers: r0/d0, v0/w0. Patch by Brendon Cahoon. llvm-svn: 328120 --- llvm/lib/Target/Hexagon/HexagonSubtarget.cpp | 56 +++++++++++++------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp index 10f7935b1165..810d540411de 100644 --- a/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSubtarget.cpp @@ -208,9 +208,11 @@ bool HexagonSubtarget::CallMutation::shouldTFRICallBind( void HexagonSubtarget::CallMutation::apply(ScheduleDAGInstrs *DAGInstrs) { ScheduleDAGMI *DAG = static_cast(DAGInstrs); SUnit* LastSequentialCall = nullptr; - unsigned VRegHoldingRet = 0; - unsigned RetRegister; - SUnit* LastUseOfRet = nullptr; + // Map from virtual register to physical register from the copy. + DenseMap VRegHoldingReg; + // Map from the physical register to the instruction that uses virtual + // register. This is used to create the barrier edge. + DenseMap LastVRegUse; auto &TRI = *DAG->MF.getSubtarget().getRegisterInfo(); auto &HII = *DAG->MF.getSubtarget().getInstrInfo(); @@ -227,8 +229,10 @@ void HexagonSubtarget::CallMutation::apply(ScheduleDAGInstrs *DAGInstrs) { else if (SchedPredsCloser && LastSequentialCall && su > 1 && su < e-1 && shouldTFRICallBind(HII, DAG->SUnits[su], DAG->SUnits[su+1])) DAG->addEdge(&DAG->SUnits[su], SDep(&DAG->SUnits[su-1], SDep::Barrier)); - // Prevent redundant register copies between two calls, which are caused by - // both the return value and the argument for the next call being in %r0. + // Prevent redundant register copies due to reads and writes of physical + // registers. The original motivation for this was the code generated + // between two calls, which are caused both the return value and the + // argument for the next call being in %r0. // Example: // 1: // 2: %vreg = COPY %r0 @@ -237,21 +241,37 @@ void HexagonSubtarget::CallMutation::apply(ScheduleDAGInstrs *DAGInstrs) { // 5: // The scheduler would often swap 3 and 4, so an additional register is // needed. This code inserts a Barrier dependence between 3 & 4 to prevent - // this. The same applies for %d0 and %v0/%w0, which are also handled. + // this. + // The code below checks for all the physical registers, not just R0/D0/V0. else if (SchedRetvalOptimization) { const MachineInstr *MI = DAG->SUnits[su].getInstr(); - if (MI->isCopy() && (MI->readsRegister(Hexagon::R0, &TRI) || - MI->readsRegister(Hexagon::V0, &TRI))) { - // %vreg = COPY %r0 - VRegHoldingRet = MI->getOperand(0).getReg(); - RetRegister = MI->getOperand(1).getReg(); - LastUseOfRet = nullptr; - } else if (VRegHoldingRet && MI->readsVirtualRegister(VRegHoldingRet)) - // - LastUseOfRet = &DAG->SUnits[su]; - else if (LastUseOfRet && MI->definesRegister(RetRegister, &TRI)) - // %r0 = ... - DAG->addEdge(&DAG->SUnits[su], SDep(LastUseOfRet, SDep::Barrier)); + if (MI->isCopy() && + TargetRegisterInfo::isPhysicalRegister(MI->getOperand(1).getReg())) { + // %vregX = COPY %r0 + VRegHoldingReg[MI->getOperand(0).getReg()] = MI->getOperand(1).getReg(); + LastVRegUse.erase(MI->getOperand(1).getReg()); + } else { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) + continue; + if (MO.isUse() && !MI->isCopy() && + VRegHoldingReg.count(MO.getReg())) { + // + LastVRegUse[VRegHoldingReg[MO.getReg()]] = &DAG->SUnits[su]; + } else if (MO.isDef() && + TargetRegisterInfo::isPhysicalRegister(MO.getReg())) { + for (MCRegAliasIterator AI(MO.getReg(), &TRI, true); AI.isValid(); + ++AI) { + if (LastVRegUse.count(*AI) && + LastVRegUse[*AI] != &DAG->SUnits[su]) + // %r0 = ... + DAG->addEdge(&DAG->SUnits[su], SDep(LastVRegUse[*AI], SDep::Barrier)); + LastVRegUse.erase(*AI); + } + } + } + } } } }