MachineBasicBlock* SystemZTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { const SystemZInstrInfo &TII = *TM.getInstrInfo(); DebugLoc dl = MI->getDebugLoc(); assert((MI->getOpcode() == SystemZ::Select32 || MI->getOpcode() == SystemZ::SelectF32 || MI->getOpcode() == SystemZ::Select64 || MI->getOpcode() == SystemZ::SelectF64) && "Unexpected instr type to insert"); // To "insert" a SELECT instruction, we actually have to insert the diamond // control-flow pattern. The incoming instruction knows the destination vreg // to set, the condition code register to branch on, the true/false values to // select between, and a branch opcode to use. const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator I = BB; ++I; // thisMBB: // ... // TrueVal = ... // cmpTY ccX, r1, r2 // jCC copy1MBB // fallthrough --> copy0MBB MachineBasicBlock *thisMBB = BB; MachineFunction *F = BB->getParent(); MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); SystemZCC::CondCodes CC = (SystemZCC::CondCodes)MI->getOperand(3).getImm(); BuildMI(BB, dl, TII.getBrCond(CC)).addMBB(copy1MBB); F->insert(I, copy0MBB); F->insert(I, copy1MBB); // Update machine-CFG edges by transferring all successors of the current // block to the new block which will contain the Phi node for the select. copy1MBB->transferSuccessors(BB); // Next, add the true and fallthrough blocks as its successors. BB->addSuccessor(copy0MBB); BB->addSuccessor(copy1MBB); // copy0MBB: // %FalseValue = ... // # fallthrough to copy1MBB BB = copy0MBB; // Update machine-CFG edges BB->addSuccessor(copy1MBB); // copy1MBB: // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] // ... BB = copy1MBB; BuildMI(BB, dl, TII.get(SystemZ::PHI), MI->getOperand(0).getReg()) .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. return BB; }
void HexagonHazardRecognizer::EmitInstruction(SUnit *SU) { MachineInstr *MI = SU->getInstr(); if (!MI) return; // Keep the set of definitions for each packet, which is used to determine // if a .new can be used. for (const MachineOperand &MO : MI->operands()) if (MO.isReg() && MO.isDef() && !MO.isImplicit()) RegDefs.insert(MO.getReg()); if (TII->isZeroCost(MI->getOpcode())) return; if (!Resources->canReserveResources(*MI)) { // It must be a .new store since other instructions must be able to be // reserved at this point. assert(TII->mayBeNewStore(*MI) && "Expecting .new store"); MachineFunction *MF = MI->getParent()->getParent(); MachineInstr *NewMI = MF->CreateMachineInstr(TII->get(TII->getDotNewOp(*MI)), MI->getDebugLoc()); assert(Resources->canReserveResources(*NewMI)); Resources->reserveResources(*NewMI); MF->DeleteMachineInstr(NewMI); } else Resources->reserveResources(*MI); LLVM_DEBUG(dbgs() << " Add instruction " << *MI); // When scheduling a dot cur instruction, check if there is an instruction // that can use the dot cur in the same packet. If so, we'll attempt to // schedule it before other instructions. We only do this if the load has a // single zero-latency use. if (TII->mayBeCurLoad(*MI)) for (auto &S : SU->Succs) if (S.isAssignedRegDep() && S.getLatency() == 0 && S.getSUnit()->NumPredsLeft == 1) { UsesDotCur = S.getSUnit(); DotCurPNum = PacketNum; break; } if (SU == UsesDotCur) { UsesDotCur = nullptr; DotCurPNum = -1; } UsesLoad = MI->mayLoad(); if (TII->isHVXVec(*MI) && !MI->mayLoad() && !MI->mayStore()) for (auto &S : SU->Succs) if (S.isAssignedRegDep() && S.getLatency() == 0 && TII->mayBeNewStore(*S.getSUnit()->getInstr()) && Resources->canReserveResources(*S.getSUnit()->getInstr())) { PrefVectorStoreNew = S.getSUnit(); break; } }
bool PHIElimination::runOnMachineFunction(MachineFunction &MF) { MRI = &MF.getRegInfo(); LV = getAnalysisIfAvailable<LiveVariables>(); LIS = getAnalysisIfAvailable<LiveIntervals>(); bool Changed = false; // This pass takes the function out of SSA form. MRI->leaveSSA(); // Split critical edges to help the coalescer. This does not yet support // updating LiveIntervals, so we disable it. if (!DisableEdgeSplitting && (LV || LIS)) { MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>(); for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) Changed |= SplitPHIEdges(MF, *I, MLI); } // Populate VRegPHIUseCount analyzePHINodes(MF); // Eliminate PHI instructions by inserting copies into predecessor blocks. for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) Changed |= EliminatePHINodes(MF, *I); // Remove dead IMPLICIT_DEF instructions. for (SmallPtrSet<MachineInstr*, 4>::iterator I = ImpDefs.begin(), E = ImpDefs.end(); I != E; ++I) { MachineInstr *DefMI = *I; unsigned DefReg = DefMI->getOperand(0).getReg(); if (MRI->use_nodbg_empty(DefReg)) { if (LIS) LIS->RemoveMachineInstrFromMaps(DefMI); DefMI->eraseFromParent(); } } // Clean up the lowered PHI instructions. for (LoweredPHIMap::iterator I = LoweredPHIs.begin(), E = LoweredPHIs.end(); I != E; ++I) { if (LIS) LIS->RemoveMachineInstrFromMaps(I->first); MF.DeleteMachineInstr(I->first); } LoweredPHIs.clear(); ImpDefs.clear(); VRegPHIUseCount.clear(); return Changed; }
bool PHIElimination::runOnMachineFunction(MachineFunction &MF) { MRI = &MF.getRegInfo(); bool Changed = false; // Split critical edges to help the coalescer if (!DisableEdgeSplitting) { if (LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>()) { MachineLoopInfo *MLI = getAnalysisIfAvailable<MachineLoopInfo>(); for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) Changed |= SplitPHIEdges(MF, *I, *LV, MLI); } } // Populate VRegPHIUseCount analyzePHINodes(MF); // Eliminate PHI instructions by inserting copies into predecessor blocks. for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) Changed |= EliminatePHINodes(MF, *I); // Remove dead IMPLICIT_DEF instructions. for (SmallPtrSet<MachineInstr*, 4>::iterator I = ImpDefs.begin(), E = ImpDefs.end(); I != E; ++I) { MachineInstr *DefMI = *I; unsigned DefReg = DefMI->getOperand(0).getReg(); if (MRI->use_nodbg_empty(DefReg)) DefMI->eraseFromParent(); } // Clean up the lowered PHI instructions. for (LoweredPHIMap::iterator I = LoweredPHIs.begin(), E = LoweredPHIs.end(); I != E; ++I) MF.DeleteMachineInstr(I->first); LoweredPHIs.clear(); ImpDefs.clear(); VRegPHIUseCount.clear(); return Changed; }
ScheduleHazardRecognizer::HazardType HexagonHazardRecognizer::getHazardType(SUnit *SU, int stalls) { MachineInstr *MI = SU->getInstr(); if (!MI || TII->isZeroCost(MI->getOpcode())) return NoHazard; if (!Resources->canReserveResources(*MI)) { LLVM_DEBUG(dbgs() << "*** Hazard in cycle " << PacketNum << ", " << *MI); HazardType RetVal = Hazard; if (TII->mayBeNewStore(*MI)) { // Make sure the register to be stored is defined by an instruction in the // packet. MachineOperand &MO = MI->getOperand(MI->getNumOperands() - 1); if (!MO.isReg() || RegDefs.count(MO.getReg()) == 0) return Hazard; // The .new store version uses different resources so check if it // causes a hazard. MachineFunction *MF = MI->getParent()->getParent(); MachineInstr *NewMI = MF->CreateMachineInstr(TII->get(TII->getDotNewOp(*MI)), MI->getDebugLoc()); if (Resources->canReserveResources(*NewMI)) RetVal = NoHazard; LLVM_DEBUG(dbgs() << "*** Try .new version? " << (RetVal == NoHazard) << "\n"); MF->DeleteMachineInstr(NewMI); } return RetVal; } if (SU == UsesDotCur && DotCurPNum != (int)PacketNum) { LLVM_DEBUG(dbgs() << "*** .cur Hazard in cycle " << PacketNum << ", " << *MI); return Hazard; } return NoHazard; }
MachineBasicBlock * AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); assert((MI->getOpcode() == Alpha::CAS32 || MI->getOpcode() == Alpha::CAS64 || MI->getOpcode() == Alpha::LAS32 || MI->getOpcode() == Alpha::LAS64 || MI->getOpcode() == Alpha::SWAP32 || MI->getOpcode() == Alpha::SWAP64) && "Unexpected instr type to insert"); bool is32 = MI->getOpcode() == Alpha::CAS32 || MI->getOpcode() == Alpha::LAS32 || MI->getOpcode() == Alpha::SWAP32; //Load locked store conditional for atomic ops take on the same form //start: //ll //do stuff (maybe branch to exit) //sc //test sc and maybe branck to start //exit: const BasicBlock *LLVM_BB = BB->getBasicBlock(); DebugLoc dl = MI->getDebugLoc(); MachineFunction::iterator It = BB; ++It; MachineBasicBlock *thisMBB = BB; MachineFunction *F = BB->getParent(); MachineBasicBlock *llscMBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); sinkMBB->transferSuccessors(thisMBB); F->insert(It, llscMBB); F->insert(It, sinkMBB); BuildMI(thisMBB, dl, TII->get(Alpha::BR)).addMBB(llscMBB); unsigned reg_res = MI->getOperand(0).getReg(), reg_ptr = MI->getOperand(1).getReg(), reg_v2 = MI->getOperand(2).getReg(), reg_store = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass); BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::LDL_L : Alpha::LDQ_L), reg_res).addImm(0).addReg(reg_ptr); switch (MI->getOpcode()) { case Alpha::CAS32: case Alpha::CAS64: { unsigned reg_cmp = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass); BuildMI(llscMBB, dl, TII->get(Alpha::CMPEQ), reg_cmp) .addReg(reg_v2).addReg(reg_res); BuildMI(llscMBB, dl, TII->get(Alpha::BEQ)) .addImm(0).addReg(reg_cmp).addMBB(sinkMBB); BuildMI(llscMBB, dl, TII->get(Alpha::BISr), reg_store) .addReg(Alpha::R31).addReg(MI->getOperand(3).getReg()); break; } case Alpha::LAS32: case Alpha::LAS64: { BuildMI(llscMBB, dl,TII->get(is32 ? Alpha::ADDLr : Alpha::ADDQr), reg_store) .addReg(reg_res).addReg(reg_v2); break; } case Alpha::SWAP32: case Alpha::SWAP64: { BuildMI(llscMBB, dl, TII->get(Alpha::BISr), reg_store) .addReg(reg_v2).addReg(reg_v2); break; } } BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::STL_C : Alpha::STQ_C), reg_store) .addReg(reg_store).addImm(0).addReg(reg_ptr); BuildMI(llscMBB, dl, TII->get(Alpha::BEQ)) .addImm(0).addReg(reg_store).addMBB(llscMBB); BuildMI(llscMBB, dl, TII->get(Alpha::BR)).addMBB(sinkMBB); thisMBB->addSuccessor(llscMBB); llscMBB->addSuccessor(llscMBB); llscMBB->addSuccessor(sinkMBB); F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. return sinkMBB; }
MachineBasicBlock* MSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, MachineBasicBlock *BB) const { MachineFunction *F = BB->getParent(); MachineRegisterInfo &RI = F->getRegInfo(); DebugLoc dl = MI->getDebugLoc(); const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); unsigned Opc; const TargetRegisterClass * RC; switch (MI->getOpcode()) { default: assert(0 && "Invalid shift opcode!"); case MSP430::Shl8: Opc = MSP430::SHL8r1; RC = MSP430::GR8RegisterClass; break; case MSP430::Shl16: Opc = MSP430::SHL16r1; RC = MSP430::GR16RegisterClass; break; case MSP430::Sra8: Opc = MSP430::SAR8r1; RC = MSP430::GR8RegisterClass; break; case MSP430::Sra16: Opc = MSP430::SAR16r1; RC = MSP430::GR16RegisterClass; break; case MSP430::Srl8: Opc = MSP430::SAR8r1c; RC = MSP430::GR8RegisterClass; break; case MSP430::Srl16: Opc = MSP430::SAR16r1c; RC = MSP430::GR16RegisterClass; break; } const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator I = BB; ++I; // Create loop block MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); F->insert(I, LoopBB); F->insert(I, RemBB); // Update machine-CFG edges by transferring all successors of the current // block to the block containing instructions after shift. RemBB->transferSuccessors(BB); // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB BB->addSuccessor(LoopBB); BB->addSuccessor(RemBB); LoopBB->addSuccessor(RemBB); LoopBB->addSuccessor(LoopBB); unsigned ShiftAmtReg = RI.createVirtualRegister(MSP430::GR8RegisterClass); unsigned ShiftAmtReg2 = RI.createVirtualRegister(MSP430::GR8RegisterClass); unsigned ShiftReg = RI.createVirtualRegister(RC); unsigned ShiftReg2 = RI.createVirtualRegister(RC); unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); unsigned SrcReg = MI->getOperand(1).getReg(); unsigned DstReg = MI->getOperand(0).getReg(); // BB: // cmp 0, N // je RemBB BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) .addReg(ShiftAmtSrcReg).addImm(0); BuildMI(BB, dl, TII.get(MSP430::JCC)) .addMBB(RemBB) .addImm(MSP430CC::COND_E); // LoopBB: // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] // ShiftReg2 = shift ShiftReg // ShiftAmt2 = ShiftAmt - 1; BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) .addReg(SrcReg).addMBB(BB) .addReg(ShiftReg2).addMBB(LoopBB); BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) .addReg(ShiftAmtSrcReg).addMBB(BB) .addReg(ShiftAmtReg2).addMBB(LoopBB); BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) .addReg(ShiftReg); BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) .addReg(ShiftAmtReg).addImm(1); BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) .addMBB(LoopBB) .addImm(MSP430CC::COND_NE); // RemBB: // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] BuildMI(RemBB, dl, TII.get(MSP430::PHI), DstReg) .addReg(SrcReg).addMBB(BB) .addReg(ShiftReg2).addMBB(LoopBB); F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. return RemBB; }
MachineBasicBlock * SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); unsigned BROpcode; unsigned CC; DebugLoc dl = MI->getDebugLoc(); // Figure out the conditional branch opcode to use for this select_cc. switch (MI->getOpcode()) { default: llvm_unreachable("Unknown SELECT_CC!"); case SP::SELECT_CC_Int_ICC: case SP::SELECT_CC_FP_ICC: case SP::SELECT_CC_DFP_ICC: BROpcode = SP::BCOND; break; case SP::SELECT_CC_Int_FCC: case SP::SELECT_CC_FP_FCC: case SP::SELECT_CC_DFP_FCC: BROpcode = SP::FBCOND; break; } CC = (SPCC::CondCodes)MI->getOperand(3).getImm(); // To "insert" a SELECT_CC instruction, we actually have to insert the diamond // control-flow pattern. The incoming instruction knows the destination vreg // to set, the condition code register to branch on, the true/false values to // select between, and a branch opcode to use. const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator It = BB; ++It; // thisMBB: // ... // TrueVal = ... // [f]bCC copy1MBB // fallthrough --> copy0MBB MachineBasicBlock *thisMBB = BB; MachineFunction *F = BB->getParent(); MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); BuildMI(BB, dl, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC); F->insert(It, copy0MBB); F->insert(It, sinkMBB); // Update machine-CFG edges by first adding all successors of the current // block to the new block which will contain the Phi node for the select. for (MachineBasicBlock::succ_iterator I = BB->succ_begin(), E = BB->succ_end(); I != E; ++I) sinkMBB->addSuccessor(*I); // Next, remove all successors of the current block, and add the true // and fallthrough blocks as its successors. while (!BB->succ_empty()) BB->removeSuccessor(BB->succ_begin()); // Next, add the true and fallthrough blocks as its successors. BB->addSuccessor(copy0MBB); BB->addSuccessor(sinkMBB); // copy0MBB: // %FalseValue = ... // # fallthrough to sinkMBB BB = copy0MBB; // Update machine-CFG edges BB->addSuccessor(sinkMBB); // sinkMBB: // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] // ... BB = sinkMBB; BuildMI(BB, dl, TII.get(SP::PHI), MI->getOperand(0).getReg()) .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. return BB; }
MachineBasicBlock * MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); bool isFPCmp = false; DebugLoc dl = MI->getDebugLoc(); switch (MI->getOpcode()) { default: assert(false && "Unexpected instr type to insert"); case Mips::Select_FCC: case Mips::Select_FCC_S32: case Mips::Select_FCC_D32: isFPCmp = true; // FALL THROUGH case Mips::Select_CC: case Mips::Select_CC_S32: case Mips::Select_CC_D32: { // To "insert" a SELECT_CC instruction, we actually have to insert the // diamond control-flow pattern. The incoming instruction knows the // destination vreg to set, the condition code register to branch on, the // true/false values to select between, and a branch opcode to use. const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator It = BB; ++It; // thisMBB: // ... // TrueVal = ... // setcc r1, r2, r3 // bNE r1, r0, copy1MBB // fallthrough --> copy0MBB MachineBasicBlock *thisMBB = BB; MachineFunction *F = BB->getParent(); MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); // Emit the right instruction according to the type of the operands compared if (isFPCmp) { // Find the condiction code present in the setcc operation. Mips::CondCode CC = (Mips::CondCode)MI->getOperand(4).getImm(); // Get the branch opcode from the branch code. unsigned Opc = FPBranchCodeToOpc(GetFPBranchCodeFromCond(CC)); BuildMI(BB, dl, TII->get(Opc)).addMBB(sinkMBB); } else BuildMI(BB, dl, TII->get(Mips::BNE)).addReg(MI->getOperand(1).getReg()) .addReg(Mips::ZERO).addMBB(sinkMBB); F->insert(It, copy0MBB); F->insert(It, sinkMBB); // Update machine-CFG edges by first adding all successors of the current // block to the new block which will contain the Phi node for the select. for(MachineBasicBlock::succ_iterator i = BB->succ_begin(), e = BB->succ_end(); i != e; ++i) sinkMBB->addSuccessor(*i); // Next, remove all successors of the current block, and add the true // and fallthrough blocks as its successors. while(!BB->succ_empty()) BB->removeSuccessor(BB->succ_begin()); BB->addSuccessor(copy0MBB); BB->addSuccessor(sinkMBB); // copy0MBB: // %FalseValue = ... // # fallthrough to sinkMBB BB = copy0MBB; // Update machine-CFG edges BB->addSuccessor(sinkMBB); // sinkMBB: // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] // ... BB = sinkMBB; BuildMI(BB, dl, TII->get(Mips::PHI), MI->getOperand(0).getReg()) .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) .addReg(MI->getOperand(3).getReg()).addMBB(thisMBB); F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. return BB; } } }