bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); assert(ISel && "Cannot work without InstructionSelector"); // FIXME: freezeReservedRegs is now done in IRTranslator, but there are many // other MF/MFI fields we need to initialize. #ifndef NDEBUG // FIXME: We could introduce new blocks and will need to fix the outer loop. // Until then, keep track of the number of blocks to assert that we don't. const size_t NumBlocks = MF.size(); #endif for (MachineBasicBlock *MBB : post_order(&MF)) { for (MachineBasicBlock::reverse_iterator MII = MBB->rbegin(), End = MBB->rend(); MII != End;) { MachineInstr &MI = *MII++; DEBUG(dbgs() << "Selecting: " << MI << '\n'); if (!ISel->select(MI)) reportSelectionError(MI, "Cannot select"); // FIXME: It would be nice to dump all inserted instructions. It's not // obvious how, esp. considering select() can insert after MI. } } assert(MF.size() == NumBlocks && "Inserting blocks is not supported yet"); // Check that we did select everything. Do this separately to make sure we // didn't miss any newly inserted instructions. // FIXME: This (and other checks) should move into a verifier, predicated on // a "post-isel" MachineFunction property. That would also let us selectively // enable it depending on build configuration. for (MachineBasicBlock &MBB : MF) { for (MachineInstr &MI : MBB) { if (isPreISelGenericOpcode(MI.getOpcode())) { reportSelectionError( MI, "Generic instruction survived instruction selection"); } } } // Now that selection is complete, there are no more generic vregs. // FIXME: We're still discussing what to do with the vreg->size map: // it's somewhat redundant (with the def MIs type size), but having to // examine MIs is also awkward. Another alternative is to track the type on // the vreg instead, but that's not ideal either, because it's saying that // vregs have types, which they really don't. But then again, LLT is just // a size and a "shape": it's probably the same information as regbank info. MF.getRegInfo().clearVirtRegSizes(); // FIXME: Should we accurately track changes? return true; }
MachineFunction* Disassembler::disassemble(unsigned Address) { MachineFunction *MF = getOrCreateFunction(Address); if (MF->size() == 0) { // Decode basic blocks until end of function unsigned Size = 0; MachineBasicBlock *MBB; do { unsigned MBBSize = 0; MBB = decodeBasicBlock(Address+Size, MF, MBBSize); Size += MBBSize; } while (Address+Size < CurSectionEnd && MBB->size() > 0 && !(MBB->instr_rbegin()->isReturn())); if (Address+Size < CurSectionEnd && MBB->size() > 0) { // FIXME: This can be shoved into the loop above to improve performance MachineFunction *NextMF = getNearestFunction(getDebugOffset(MBB->instr_rbegin()->getDebugLoc())); if (NextMF != NULL) { Functions.erase( getDebugOffset(NextMF->begin()->instr_begin()->getDebugLoc())); } } } Functions[Address] = MF; return MF; }
void X86RetpolineThunks::populateThunk(MachineFunction &MF, unsigned Reg) { // Set MF properties. We never use vregs... MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs); // Grab the entry MBB and erase any other blocks. O0 codegen appears to // generate two bbs for the entry block. MachineBasicBlock *Entry = &MF.front(); Entry->clear(); while (MF.size() > 1) MF.erase(std::next(MF.begin())); MachineBasicBlock *CaptureSpec = MF.CreateMachineBasicBlock(Entry->getBasicBlock()); MachineBasicBlock *CallTarget = MF.CreateMachineBasicBlock(Entry->getBasicBlock()); MCSymbol *TargetSym = MF.getContext().createTempSymbol(); MF.push_back(CaptureSpec); MF.push_back(CallTarget); const unsigned CallOpc = Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32; const unsigned RetOpc = Is64Bit ? X86::RETQ : X86::RETL; Entry->addLiveIn(Reg); BuildMI(Entry, DebugLoc(), TII->get(CallOpc)).addSym(TargetSym); // The MIR verifier thinks that the CALL in the entry block will fall through // to CaptureSpec, so mark it as the successor. Technically, CaptureTarget is // the successor, but the MIR verifier doesn't know how to cope with that. Entry->addSuccessor(CaptureSpec); // In the capture loop for speculation, we want to stop the processor from // speculating as fast as possible. On Intel processors, the PAUSE instruction // will block speculation without consuming any execution resources. On AMD // processors, the PAUSE instruction is (essentially) a nop, so we also use an // LFENCE instruction which they have advised will stop speculation as well // with minimal resource utilization. We still end the capture with a jump to // form an infinite loop to fully guarantee that no matter what implementation // of the x86 ISA, speculating this code path never escapes. BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::PAUSE)); BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::LFENCE)); BuildMI(CaptureSpec, DebugLoc(), TII->get(X86::JMP_1)).addMBB(CaptureSpec); CaptureSpec->setHasAddressTaken(); CaptureSpec->addSuccessor(CaptureSpec); CallTarget->addLiveIn(Reg); CallTarget->setHasAddressTaken(); CallTarget->setAlignment(4); insertRegReturnAddrClobber(*CallTarget, Reg); CallTarget->back().setPreInstrSymbol(MF, TargetSym); BuildMI(CallTarget, DebugLoc(), TII->get(RetOpc)); }
bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { // If the ISel pipeline failed, do not bother running that pass. if (MF.getProperties().hasProperty( MachineFunctionProperties::Property::FailedISel)) return false; LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); CodeGenCoverage CoverageInfo; assert(ISel && "Cannot work without InstructionSelector"); // An optimization remark emitter. Used to report failures. MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); // FIXME: There are many other MF/MFI fields we need to initialize. MachineRegisterInfo &MRI = MF.getRegInfo(); #ifndef NDEBUG // Check that our input is fully legal: we require the function to have the // Legalized property, so it should be. // FIXME: This should be in the MachineVerifier, as the RegBankSelected // property check already is. if (!DisableGISelLegalityCheck) if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) { reportGISelFailure(MF, TPC, MORE, "gisel-select", "instruction is not legal", *MI); return false; } #endif // FIXME: We could introduce new blocks and will need to fix the outer loop. // Until then, keep track of the number of blocks to assert that we don't. const size_t NumBlocks = MF.size(); for (MachineBasicBlock *MBB : post_order(&MF)) { if (MBB->empty()) continue; // Select instructions in reverse block order. We permit erasing so have // to resort to manually iterating and recognizing the begin (rend) case. bool ReachedBegin = false; for (auto MII = std::prev(MBB->end()), Begin = MBB->begin(); !ReachedBegin;) { #ifndef NDEBUG // Keep track of the insertion range for debug printing. const auto AfterIt = std::next(MII); #endif // Select this instruction. MachineInstr &MI = *MII; // And have our iterator point to the next instruction, if there is one. if (MII == Begin) ReachedBegin = true; else --MII; LLVM_DEBUG(dbgs() << "Selecting: \n " << MI); // We could have folded this instruction away already, making it dead. // If so, erase it. if (isTriviallyDead(MI, MRI)) { LLVM_DEBUG(dbgs() << "Is dead; erasing.\n"); MI.eraseFromParentAndMarkDBGValuesForRemoval(); continue; } if (!ISel->select(MI, CoverageInfo)) { // FIXME: It would be nice to dump all inserted instructions. It's // not obvious how, esp. considering select() can insert after MI. reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select", MI); return false; } // Dump the range of instructions that MI expanded into. LLVM_DEBUG({ auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII); dbgs() << "Into:\n"; for (auto &InsertedMI : make_range(InsertedBegin, AfterIt)) dbgs() << " " << InsertedMI; dbgs() << '\n'; }); } }
bool LazyLiveness::runOnMachineFunction(MachineFunction &mf) { rv.clear(); tv.clear(); backedges.clear(); backedge_source.clear(); backedge_target.clear(); calculated.clear(); preorder.clear(); rev_preorder.clear(); rv.resize(mf.size()); tv.resize(mf.size()); preorder.resize(mf.size()); rev_preorder.reserve(mf.size()); MRI = &mf.getRegInfo(); MachineDominatorTree& MDT = getAnalysis<MachineDominatorTree>(); // Step 0: Compute preorder numbering for all MBBs. unsigned num = 0; for (df_iterator<MachineDomTreeNode*> DI = df_begin(MDT.getRootNode()), DE = df_end(MDT.getRootNode()); DI != DE; ++DI) { preorder[(*DI)->getBlock()] = num++; rev_preorder.push_back((*DI)->getBlock()); } // Step 1: Compute the transitive closure of the CFG, ignoring backedges. for (po_iterator<MachineBasicBlock*> POI = po_begin(&*mf.begin()), POE = po_end(&*mf.begin()); POI != POE; ++POI) { MachineBasicBlock* MBB = *POI; SparseBitVector<128>& entry = rv[MBB]; entry.set(preorder[MBB]); for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), SE = MBB->succ_end(); SI != SE; ++SI) { DenseMap<MachineBasicBlock*, SparseBitVector<128> >::iterator SII = rv.find(*SI); // Because we're iterating in postorder, any successor that does not yet // have an rv entry must be on a backedge. if (SII != rv.end()) { entry |= SII->second; } else { backedges.insert(std::make_pair(MBB, *SI)); backedge_source.set(preorder[MBB]); backedge_target.set(preorder[*SI]); } } } for (SparseBitVector<128>::iterator I = backedge_source.begin(); I != backedge_source.end(); ++I) computeBackedgeChain(mf, rev_preorder[*I]); for (po_iterator<MachineBasicBlock*> POI = po_begin(&*mf.begin()), POE = po_end(&*mf.begin()); POI != POE; ++POI) if (!backedge_target.test(preorder[*POI])) for (MachineBasicBlock::succ_iterator SI = (*POI)->succ_begin(), SE = (*POI)->succ_end(); SI != SE; ++SI) if (!backedges.count(std::make_pair(*POI, *SI)) && tv.count(*SI)) { SparseBitVector<128> right = tv[*SI]; tv[*POI] |= right; } for (po_iterator<MachineBasicBlock*> POI = po_begin(&*mf.begin()), POE = po_end(&*mf.begin()); POI != POE; ++POI) tv[*POI].set(preorder[*POI]); return false; }
bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) { const MachineRegisterInfo &MRI = MF.getRegInfo(); // No matter what happens, whether we successfully select the function or not, // nothing is going to use the vreg types after us. Make sure they disappear. auto ClearVRegTypesOnReturn = make_scope_exit([&]() { MRI.getVRegToType().clear(); }); // If the ISel pipeline failed, do not bother running that pass. if (MF.getProperties().hasProperty( MachineFunctionProperties::Property::FailedISel)) return false; DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n'); const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>(); const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector(); assert(ISel && "Cannot work without InstructionSelector"); // An optimization remark emitter. Used to report failures. MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr); // FIXME: freezeReservedRegs is now done in IRTranslator, but there are many // other MF/MFI fields we need to initialize. #ifndef NDEBUG // Check that our input is fully legal: we require the function to have the // Legalized property, so it should be. // FIXME: This should be in the MachineVerifier, but it can't use the // LegalizerInfo as it's currently in the separate GlobalISel library. // The RegBankSelected property is already checked in the verifier. Note // that it has the same layering problem, but we only use inline methods so // end up not needing to link against the GlobalISel library. if (const LegalizerInfo *MLI = MF.getSubtarget().getLegalizerInfo()) for (MachineBasicBlock &MBB : MF) for (MachineInstr &MI : MBB) if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI)) { reportGISelFailure(MF, TPC, MORE, "gisel-select", "instruction is not legal", MI); return false; } #endif // FIXME: We could introduce new blocks and will need to fix the outer loop. // Until then, keep track of the number of blocks to assert that we don't. const size_t NumBlocks = MF.size(); for (MachineBasicBlock *MBB : post_order(&MF)) { if (MBB->empty()) continue; // Select instructions in reverse block order. We permit erasing so have // to resort to manually iterating and recognizing the begin (rend) case. bool ReachedBegin = false; for (auto MII = std::prev(MBB->end()), Begin = MBB->begin(); !ReachedBegin;) { #ifndef NDEBUG // Keep track of the insertion range for debug printing. const auto AfterIt = std::next(MII); #endif // Select this instruction. MachineInstr &MI = *MII; // And have our iterator point to the next instruction, if there is one. if (MII == Begin) ReachedBegin = true; else --MII; DEBUG(dbgs() << "Selecting: \n " << MI); if (!ISel->select(MI)) { // FIXME: It would be nice to dump all inserted instructions. It's // not obvious how, esp. considering select() can insert after MI. reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select", MI); return false; } // Dump the range of instructions that MI expanded into. DEBUG({ auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII); dbgs() << "Into:\n"; for (auto &InsertedMI : make_range(InsertedBegin, AfterIt)) dbgs() << " " << InsertedMI; dbgs() << '\n'; }); } }