コード例 #1
0
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;
}
コード例 #2
0
ファイル: Disassembler.cpp プロジェクト: SAB2012/fracture
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;
}
コード例 #3
0
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));
}
コード例 #4
0
ファイル: InstructionSelect.cpp プロジェクト: happz/llvm
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';
      });
    }
  }
コード例 #5
0
ファイル: LazyLiveness.cpp プロジェクト: Killfrra/llvm-kernel
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;
}
コード例 #6
0
ファイル: InstructionSelect.cpp プロジェクト: bugsnag/llvm
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';
      });
    }
  }