bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
  MachineBranchProbabilityInfo &MBPI =
      getAnalysis<MachineBranchProbabilityInfo>();
  MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
  if (!MBFI)
    MBFI.reset(new ImplType);
  MBFI->calculate(F, MBPI, MLI);
#ifndef NDEBUG
  if (ViewMachineBlockFreqPropagationDAG != GVDT_None &&
      (ViewBlockFreqFuncName.empty() ||
       F.getName().equals(ViewBlockFreqFuncName))) {
    view();
  }
#endif
  return false;
}
Exemple #2
0
bool CalculateSpillWeights::runOnMachineFunction(MachineFunction &MF) {

  DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
               << "********** Function: " << MF.getName() << '\n');

  LiveIntervals &LIS = getAnalysis<LiveIntervals>();
  MachineRegisterInfo &MRI = MF.getRegInfo();
  VirtRegAuxInfo VRAI(MF, LIS, getAnalysis<MachineLoopInfo>());
  for (unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
    unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
    if (MRI.reg_nodbg_empty(Reg))
      continue;
    VRAI.CalculateWeightAndHint(LIS.getInterval(Reg));
  }
  return false;
}
/// Calculate the liveness information for the given machine function.
bool StackMapLiveness::runOnMachineFunction(MachineFunction &MF) {
  if (!EnablePatchPointLiveness)
    return false;

  DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: " << MF.getName()
               << " **********\n");
  TRI = MF.getSubtarget().getRegisterInfo();
  ++NumStackMapFuncVisited;

  // Skip this function if there are no patchpoints to process.
  if (!MF.getFrameInfo().hasPatchPoint()) {
    ++NumStackMapFuncSkipped;
    return false;
  }
  return calculateLiveness(MF);
}
Exemple #4
0
// Adjust local variables that are 4-bytes or larger to 4-byte boundary
void ARCFrameLowering::processFunctionBeforeFrameFinalized(
    MachineFunction &MF, RegScavenger *RS) const {
  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
  LLVM_DEBUG(dbgs() << "Process function before frame finalized: "
                    << MF.getName() << "\n");
  MachineFrameInfo &MFI = MF.getFrameInfo();
  LLVM_DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n");
  const TargetRegisterClass *RC = &ARC::GPR32RegClass;
  if (MFI.hasStackObjects()) {
    int RegScavFI = MFI.CreateStackObject(
        RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false);
    RS->addScavengingFrameIndex(RegScavFI);
    LLVM_DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI
                      << "\n");
  }
}
Exemple #5
0
bool LDVImpl::runOnMachineFunction(MachineFunction &mf) {
  clear();
  MF = &mf;
  LIS = &pass.getAnalysis<LiveIntervals>();
  MDT = &pass.getAnalysis<MachineDominatorTree>();
  TRI = mf.getSubtarget().getRegisterInfo();
  LS.initialize(mf);
  DEBUG(dbgs() << "********** COMPUTING LIVE DEBUG VARIABLES: "
               << mf.getName() << " **********\n");

  bool Changed = collectDebugValues(mf);
  computeIntervals();
  DEBUG(print(dbgs()));
  ModifiedMF = Changed;
  return Changed;
}
void llvm::calculateSpillWeightsAndHints(LiveIntervals &LIS,
                           MachineFunction &MF,
                           const MachineLoopInfo &MLI,
                           const MachineBlockFrequencyInfo &MBFI,
                           VirtRegAuxInfo::NormalizingFn norm) {
  DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
               << "********** Function: " << MF.getName() << '\n');

  MachineRegisterInfo &MRI = MF.getRegInfo();
  VirtRegAuxInfo VRAI(MF, LIS, MLI, MBFI, norm);
  for (unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
    unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
    if (MRI.reg_nodbg_empty(Reg))
      continue;
    VRAI.calculateSpillWeightAndHint(LIS.getInterval(Reg));
  }
}
Exemple #7
0
bool Combiner::combineMachineInstrs(MachineFunction &MF) {
  // If the ISel pipeline failed, do not bother running this pass.
  // FIXME: Should this be here or in individual combiner passes.
  if (MF.getProperties().hasProperty(
          MachineFunctionProperties::Property::FailedISel))
    return false;

  MRI = &MF.getRegInfo();
  Builder.setMF(MF);

  DEBUG(dbgs() << "Generic MI Combiner for: " << MF.getName() << '\n');

  MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);

  bool MFChanged = false;
  bool Changed;

  do {
    // Collect all instructions. Do a post order traversal for basic blocks and
    // insert with list bottom up, so while we pop_back_val, we'll traverse top
    // down RPOT.
    Changed = false;
    GISelWorkList<512> WorkList;
    for (MachineBasicBlock *MBB : post_order(&MF)) {
      if (MBB->empty())
        continue;
      for (auto MII = MBB->rbegin(), MIE = MBB->rend(); MII != MIE;) {
        MachineInstr *CurMI = &*MII;
        ++MII;
        // Erase dead insts before even adding to the list.
        if (isTriviallyDead(*CurMI, *MRI)) {
          DEBUG(dbgs() << *CurMI << "Is dead; erasing.\n");
          CurMI->eraseFromParentAndMarkDBGValuesForRemoval();
          continue;
        }
        WorkList.insert(CurMI);
      }
    }
    // Main Loop. Process the instructions here.
    while (!WorkList.empty()) {
      MachineInstr *CurrInst = WorkList.pop_back_val();
      DEBUG(dbgs() << "Try combining " << *CurrInst << "\n";);
      Changed |= CInfo.combine(*CurrInst, Builder);
    }
    MFChanged |= Changed;
  } while (Changed);
bool RegUsageInfoPropagationPass::runOnMachineFunction(MachineFunction &MF) {
  const Module *M = MF.getFunction().getParent();
  PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>();

  DEBUG(dbgs() << " ++++++++++++++++++++ " << getPassName()
               << " ++++++++++++++++++++  \n");
  DEBUG(dbgs() << "MachineFunction : " << MF.getName() << "\n");

  const MachineFrameInfo &MFI = MF.getFrameInfo();
  if (!MFI.hasCalls() && !MFI.hasTailCall())
    return false;

  bool Changed = false;

  for (MachineBasicBlock &MBB : MF) {
    for (MachineInstr &MI : MBB) {
      if (!MI.isCall())
        continue;
      DEBUG(dbgs()
            << "Call Instruction Before Register Usage Info Propagation : \n");
      DEBUG(dbgs() << MI << "\n");

      auto UpdateRegMask = [&](const Function *F) {
        const auto *RegMask = PRUI->getRegUsageInfo(F);
        if (!RegMask)
          return;
        setRegMask(MI, &(*RegMask)[0]);
        Changed = true;
      };

      if (const Function *F = findCalledFunction(*M, MI)) {
        UpdateRegMask(F);
      } else {
        DEBUG(dbgs() << "Failed to find call target function\n");
      }

      DEBUG(dbgs() << "Call Instruction After Register Usage Info Propagation : "
            << MI << '\n');
    }
  }

  DEBUG(dbgs() << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
                  "++++++ \n");
  return Changed;
}
Exemple #9
0
/// We need to override this function so we can avoid
/// the call to EmitFunctionHeader(), which the MCPureStreamer can't handle.
bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
  const AMDGPUSubtarget &STM = TM.getSubtarget<AMDGPUSubtarget>();
  if (STM.dumpCode()) {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    MF.dump();
#endif
  }
  SetupMachineFunction(MF);
  if (OutStreamer.hasRawTextSupport()) {
    OutStreamer.EmitRawText("@" + MF.getName() + ":");
  }
  OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
  if (STM.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
    EmitProgramInfo(MF);
  }
  EmitFunctionBody();
  return false;
}
bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
  DEBUG(dbgs() << "********** CFG Stackifying **********\n"
                  "********** Function: "
               << MF.getName() << '\n');

  const auto &MLI = getAnalysis<MachineLoopInfo>();
  const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();

  // RPO sorting needs all loops to be single-entry.
  EliminateMultipleEntryLoops(MF, MLI);

  // Sort the blocks in RPO, with contiguous loops.
  SortBlocks(MF, MLI);

  // Place the BLOCK and LOOP markers to indicate the beginnings of scopes.
  PlaceMarkers(MF, MLI, TII);

  return true;
}
Exemple #11
0
bool RABasic::runOnMachineFunction(MachineFunction &mf) {
  DEBUG(dbgs() << "********** BASIC REGISTER ALLOCATION **********\n"
               << "********** Function: "
               << mf.getName() << '\n');

  MF = &mf;
  RegAllocBase::init(getAnalysis<VirtRegMap>(),
                     getAnalysis<LiveIntervals>(),
                     getAnalysis<LiveRegMatrix>());
  SpillerInstance.reset(createInlineSpiller(*this, *MF, *VRM));

  allocatePhysRegs();

  // Diagnostic output before rewriting
  DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << *VRM << "\n");

  releaseMemory();
  return true;
}
Exemple #12
0
void MIRPrinter::print(const MachineFunction &MF) {
  initRegisterMaskIds(MF);

  yaml::MachineFunction YamlMF;
  YamlMF.Name = MF.getName();
  YamlMF.Alignment = MF.getAlignment();
  YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice();
  YamlMF.HasWinCFI = MF.hasWinCFI();

  YamlMF.Legalized = MF.getProperties().hasProperty(
      MachineFunctionProperties::Property::Legalized);
  YamlMF.RegBankSelected = MF.getProperties().hasProperty(
      MachineFunctionProperties::Property::RegBankSelected);
  YamlMF.Selected = MF.getProperties().hasProperty(
      MachineFunctionProperties::Property::Selected);
  YamlMF.FailedISel = MF.getProperties().hasProperty(
      MachineFunctionProperties::Property::FailedISel);

  convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
  ModuleSlotTracker MST(MF.getFunction().getParent());
  MST.incorporateFunction(MF.getFunction());
  convert(MST, YamlMF.FrameInfo, MF.getFrameInfo());
  convertStackObjects(YamlMF, MF, MST);
  if (const auto *ConstantPool = MF.getConstantPool())
    convert(YamlMF, *ConstantPool);
  if (const auto *JumpTableInfo = MF.getJumpTableInfo())
    convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo);
  raw_string_ostream StrOS(YamlMF.Body.Value.Value);
  bool IsNewlineNeeded = false;
  for (const auto &MBB : MF) {
    if (IsNewlineNeeded)
      StrOS << "\n";
    MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
        .print(MBB);
    IsNewlineNeeded = true;
  }
  StrOS.flush();
  yaml::Output Out(OS);
  if (!SimplifyMIR)
      Out.setWriteDefaultValues(true);
  Out << YamlMF;
}
bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
  DEBUG(dbgs() << "********** CFG Stackifying **********\n"
                  "********** Function: "
               << MF.getName() << '\n');

  const auto &MLI = getAnalysis<MachineLoopInfo>();
  auto &MDT = getAnalysis<MachineDominatorTree>();
  // Liveness is not tracked for EXPR_STACK physreg.
  const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
  WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
  MF.getRegInfo().invalidateLiveness();

  // Sort the blocks, with contiguous loops.
  SortBlocks(MF, MLI, MDT);

  // Place the BLOCK and LOOP markers to indicate the beginnings of scopes.
  PlaceMarkers(MF, MLI, TII, MDT, MFI);

  return true;
}
bool WebAssemblyOptimizeLiveIntervals::runOnMachineFunction(MachineFunction &MF) {
  LLVM_DEBUG(dbgs() << "********** Optimize LiveIntervals **********\n"
                       "********** Function: "
                    << MF.getName() << '\n');

  MachineRegisterInfo &MRI = MF.getRegInfo();
  LiveIntervals &LIS = getAnalysis<LiveIntervals>();

  // We don't preserve SSA form.
  MRI.leaveSSA();

  assert(MRI.tracksLiveness() &&
         "OptimizeLiveIntervals expects liveness");

  // Split multiple-VN LiveIntervals into multiple LiveIntervals.
  SmallVector<LiveInterval*, 4> SplitLIs;
  for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) {
    unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
    if (MRI.reg_nodbg_empty(Reg))
      continue;

    LIS.splitSeparateComponents(LIS.getInterval(Reg), SplitLIs);
    SplitLIs.clear();
  }

  // In PrepareForLiveIntervals, we conservatively inserted IMPLICIT_DEF
  // instructions to satisfy LiveIntervals' requirement that all uses be
  // dominated by defs. Now that LiveIntervals has computed which of these
  // defs are actually needed and which are dead, remove the dead ones.
  for (auto MII = MF.begin()->begin(), MIE = MF.begin()->end(); MII != MIE; ) {
    MachineInstr *MI = &*MII++;
    if (MI->isImplicitDef() && MI->getOperand(0).isDead()) {
      LiveInterval &LI = LIS.getInterval(MI->getOperand(0).getReg());
      LIS.removeVRegDefAt(LI, LIS.getInstructionIndex(*MI).getRegSlot());
      LIS.RemoveMachineInstrFromMaps(*MI);
      MI->eraseFromParent();
    }
  }

  return false;
}
void NVPTXReplaceImageHandles::
replaceImageHandle(MachineOperand &Op, MachineFunction &MF) {
  const MachineRegisterInfo &MRI = MF.getRegInfo();
  NVPTXMachineFunctionInfo *MFI = MF.getInfo<NVPTXMachineFunctionInfo>();
  // Which instruction defines the handle?
  MachineInstr *MI = MRI.getVRegDef(Op.getReg());
  assert(MI && "No def for image handle vreg?");
  MachineInstr &TexHandleDef = *MI;

  switch (TexHandleDef.getOpcode()) {
  case NVPTX::LD_i64_avar: {
    // The handle is a parameter value being loaded, replace with the
    // parameter symbol
    assert(TexHandleDef.getOperand(6).isSymbol() && "Load is not a symbol!");
    StringRef Sym = TexHandleDef.getOperand(6).getSymbolName();
    std::string ParamBaseName = MF.getName();
    ParamBaseName += "_param_";
    assert(Sym.startswith(ParamBaseName) && "Invalid symbol reference");
    unsigned Param = atoi(Sym.data()+ParamBaseName.size());
    std::string NewSym;
    raw_string_ostream NewSymStr(NewSym);
    NewSymStr << MF.getFunction()->getName() << "_param_" << Param;
    Op.ChangeToImmediate(
      MFI->getImageHandleSymbolIndex(NewSymStr.str().c_str()));
    InstrsToRemove.insert(&TexHandleDef);
    break;
  }
  case NVPTX::texsurf_handles: {
    // The handle is a global variable, replace with the global variable name
    assert(TexHandleDef.getOperand(1).isGlobal() && "Load is not a global!");
    const GlobalValue *GV = TexHandleDef.getOperand(1).getGlobal();
    assert(GV->hasName() && "Global sampler must be named!");
    Op.ChangeToImmediate(MFI->getImageHandleSymbolIndex(GV->getName().data()));
    InstrsToRemove.insert(&TexHandleDef);
    break;
  }
  default:
    llvm_unreachable("Unknown instruction operating on handle");
  }
}
void MachineFrameInfo::print(const MachineFunction &MF, raw_ostream &OS) const{
  if (Objects.empty()) return;

  const TargetFrameLowering *FI = MF.getSubtarget().getFrameLowering();
  int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0);

  OS << "Frame Objects for " << MF.getName() << ":\n";

  for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
    const StackObject &SO = Objects[i];
    OS << "  fi#" << (int)(i-NumFixedObjects) << ": ";
    if (SO.Size == ~0ULL) {
      OS << "dead\n";
      continue;
    }
    if (SO.Size == 0)
      OS << "variable sized";
    else
      OS << "size=" << SO.Size;
    OS << ", align=" << SO.Alignment;

    if (i < NumFixedObjects)
      OS << ", fixed";
    if (i < NumFixedObjects || SO.SPOffset != -1) {
      int64_t Off = SO.SPOffset - ValOffset;
      OS << ", at location [SP";
      if (Off > 0)
        OS << "+" << format_hex(Off, 5);
      else if (Off < 0)
        OS << "-" << format_hex(-Off, 5);
      OS << "]";
    }
    if (SO.isSpillSlot || SO.isStatepointSpillSlot)
      OS << ", spill_slot";
    if (SO.Alloca)
      OS << ", has_alloca:" << SO.Alloca->getName();

    OS << "\n";
  }
}
bool WebAssemblyCallIndirectFixup::runOnMachineFunction(MachineFunction &MF) {
  DEBUG(dbgs() << "********** Fixing up CALL_INDIRECTs **********\n"
               << MF.getName() << '\n');

  bool Changed = false;
  const WebAssemblyInstrInfo *TII =
      MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();

  for (MachineBasicBlock &MBB : MF) {
    for (MachineInstr &MI : MBB) {
      if (IsPseudoCallIndirect(MI)) {
        DEBUG(dbgs() << "Found call_indirect: " << MI << '\n');

        // Rewrite pseudo to non-pseudo
        const MCInstrDesc &Desc = TII->get(GetNonPseudoCallIndirectOpcode(MI));
        MI.setDesc(Desc);

        // Rewrite argument order
        auto Uses = MI.explicit_uses();
        MachineInstr::mop_iterator it = Uses.begin();
        const MachineOperand MO = *it;

        // Set up the flags immediate, which currently has no defined flags
        // so it's always zero.
        it->ChangeToImmediate(0);

        MI.addOperand(MF, MO);

        DEBUG(dbgs() << "  After transform: " << MI);
        Changed = true;
      }
    }
  }

  DEBUG(dbgs() << "\nDone fixing up CALL_INDIRECTs\n\n");

  return Changed;
}
Exemple #18
0
MachineBasicBlock::iterator ARCFrameLowering::eliminateCallFramePseudoInstr(
    MachineFunction &MF, MachineBasicBlock &MBB,
    MachineBasicBlock::iterator I) const {
  LLVM_DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getName() << "\n");
  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
  MachineInstr &Old = *I;
  DebugLoc dl = Old.getDebugLoc();
  unsigned Amt = Old.getOperand(0).getImm();
  auto *AFI = MF.getInfo<ARCFunctionInfo>();
  if (!hasFP(MF)) {
    if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN)
      AFI->MaxCallStackReq = Amt;
  } else {
    if (Amt != 0) {
      assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN ||
              Old.getOpcode() == ARC::ADJCALLSTACKUP) &&
             "Unknown Frame Pseudo.");
      bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP);
      emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII);
    }
  }
  return MBB.erase(I);
}
Exemple #19
0
bool A15SDOptimizer::runOnMachineFunction(MachineFunction &Fn) {
  if (skipFunction(*Fn.getFunction()))
    return false;

  const ARMSubtarget &STI = Fn.getSubtarget<ARMSubtarget>();
  // Since the A15SDOptimizer pass can insert VDUP instructions, it can only be
  // enabled when NEON is available.
  if (!(STI.isCortexA15() && STI.hasNEON()))
    return false;
  TII = STI.getInstrInfo();
  TRI = STI.getRegisterInfo();
  MRI = &Fn.getRegInfo();
  bool Modified = false;

  DEBUG(dbgs() << "Running on function " << Fn.getName()<< "\n");

  DeadInstr.clear();
  Replacements.clear();

  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
       ++MFI) {

    for (MachineBasicBlock::iterator MI = MFI->begin(), ME = MFI->end();
      MI != ME;) {
      Modified |= runOnInstruction(MI++);
    }

  }

  for (std::set<MachineInstr *>::iterator I = DeadInstr.begin(),
                                            E = DeadInstr.end();
                                            I != E; ++I) {
    (*I)->eraseFromParent();
  }

  return Modified;
}
Exemple #20
0
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
  auto It = Functions.find(MF.getName());
  if (It == Functions.end())
    return error(Twine("no machine function information for function '") +
                 MF.getName() + "' in the MIR file");
  // TODO: Recreate the machine function.
  const yaml::MachineFunction &YamlMF = *It->getValue();
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
  MF.setHasInlineAsm(YamlMF.HasInlineAsm);
  if (YamlMF.AllVRegsAllocated)
    MF.getProperties().set(MachineFunctionProperties::Property::AllVRegsAllocated);
  PerFunctionMIParsingState PFS(MF, SM, IRSlots);
  if (initializeRegisterInfo(PFS, YamlMF))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
      return true;
  }

  StringRef BlockStr = YamlMF.Body.Value.Value;
  SMDiagnostic Error;
  SourceMgr BlockSM;
  BlockSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &BlockSM;
  if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  if (MF.empty())
    return error(Twine("machine function '") + Twine(MF.getName()) +
                 "' requires at least one machine basic block in its body");
  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(PFS, YamlMF))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
    return true;
  // Parse the machine instructions after creating all of the MBBs so that the
  // parser can resolve the MBB references.
  StringRef InsnStr = YamlMF.Body.Value.Value;
  SourceMgr InsnSM;
  InsnSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &InsnSM;
  if (parseMachineInstructions(PFS, InsnStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  inferRegisterInfo(PFS, YamlMF);
  // FIXME: This is a temporary workaround until the reserved registers can be
  // serialized.
  MF.getRegInfo().freezeReservedRegs(MF);
  MF.verify();
  return false;
}
Exemple #21
0
bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {

  DEBUG(dbgs() << "********** Hexagon New Value Jump **********\n"
               << "********** Function: "
               << MF.getName() << "\n");

  if (skipFunction(*MF.getFunction()))
    return false;

  // If we move NewValueJump before register allocation we'll need live variable
  // analysis here too.

  QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
  QRI = static_cast<const HexagonRegisterInfo *>(
      MF.getSubtarget().getRegisterInfo());
  MBPI = &getAnalysis<MachineBranchProbabilityInfo>();

  if (DisableNewValueJumps) {
    return false;
  }

  int nvjCount = DbgNVJCount;
  int nvjGenerated = 0;

  // Loop through all the bb's of the function
  for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
        MBBb != MBBe; ++MBBb) {
    MachineBasicBlock *MBB = &*MBBb;

    DEBUG(dbgs() << "** dumping bb ** "
                 << MBB->getNumber() << "\n");
    DEBUG(MBB->dump());
    DEBUG(dbgs() << "\n" << "********** dumping instr bottom up **********\n");
    bool foundJump    = false;
    bool foundCompare = false;
    bool invertPredicate = false;
    unsigned predReg = 0; // predicate reg of the jump.
    unsigned cmpReg1 = 0;
    int cmpOp2 = 0;
    bool MO1IsKill = false;
    bool MO2IsKill = false;
    MachineBasicBlock::iterator jmpPos;
    MachineBasicBlock::iterator cmpPos;
    MachineInstr *cmpInstr = nullptr, *jmpInstr = nullptr;
    MachineBasicBlock *jmpTarget = nullptr;
    bool afterRA = false;
    bool isSecondOpReg = false;
    bool isSecondOpNewified = false;
    // Traverse the basic block - bottom up
    for (MachineBasicBlock::iterator MII = MBB->end(), E = MBB->begin();
             MII != E;) {
      MachineInstr &MI = *--MII;
      if (MI.isDebugValue()) {
        continue;
      }

      if ((nvjCount == 0) || (nvjCount > -1 && nvjCount <= nvjGenerated))
        break;

      DEBUG(dbgs() << "Instr: "; MI.dump(); dbgs() << "\n");

      if (!foundJump && (MI.getOpcode() == Hexagon::J2_jumpt ||
                         MI.getOpcode() == Hexagon::J2_jumpf ||
                         MI.getOpcode() == Hexagon::J2_jumptnewpt ||
                         MI.getOpcode() == Hexagon::J2_jumptnew ||
                         MI.getOpcode() == Hexagon::J2_jumpfnewpt ||
                         MI.getOpcode() == Hexagon::J2_jumpfnew)) {
        // This is where you would insert your compare and
        // instr that feeds compare
        jmpPos = MII;
        jmpInstr = &MI;
        predReg = MI.getOperand(0).getReg();
        afterRA = TargetRegisterInfo::isPhysicalRegister(predReg);

        // If ifconverter had not messed up with the kill flags of the
        // operands, the following check on the kill flag would suffice.
        // if(!jmpInstr->getOperand(0).isKill()) break;

        // This predicate register is live out out of BB
        // this would only work if we can actually use Live
        // variable analysis on phy regs - but LLVM does not
        // provide LV analysis on phys regs.
        //if(LVs.isLiveOut(predReg, *MBB)) break;

        // Get all the successors of this block - which will always
        // be 2. Check if the predicate register is live in in those
        // successor. If yes, we can not delete the predicate -
        // I am doing this only because LLVM does not provide LiveOut
        // at the BB level.
        bool predLive = false;
        for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
                            SIE = MBB->succ_end(); SI != SIE; ++SI) {
          MachineBasicBlock* succMBB = *SI;
         if (succMBB->isLiveIn(predReg)) {
            predLive = true;
          }
        }
        if (predLive)
          break;

        if (!MI.getOperand(1).isMBB())
          continue;
        jmpTarget = MI.getOperand(1).getMBB();
        foundJump = true;
        if (MI.getOpcode() == Hexagon::J2_jumpf ||
            MI.getOpcode() == Hexagon::J2_jumpfnewpt ||
            MI.getOpcode() == Hexagon::J2_jumpfnew) {
          invertPredicate = true;
        }
        continue;
      }

      // No new value jump if there is a barrier. A barrier has to be in its
      // own packet. A barrier has zero operands. We conservatively bail out
      // here if we see any instruction with zero operands.
      if (foundJump && MI.getNumOperands() == 0)
        break;

      if (foundJump && !foundCompare && MI.getOperand(0).isReg() &&
          MI.getOperand(0).getReg() == predReg) {

        // Not all compares can be new value compare. Arch Spec: 7.6.1.1
        if (isNewValueJumpCandidate(MI)) {

          assert(
              (MI.getDesc().isCompare()) &&
              "Only compare instruction can be collapsed into New Value Jump");
          isSecondOpReg = MI.getOperand(2).isReg();

          if (!canCompareBeNewValueJump(QII, QRI, MII, predReg, isSecondOpReg,
                                        afterRA, jmpPos, MF))
            break;

          cmpInstr = &MI;
          cmpPos = MII;
          foundCompare = true;

          // We need cmpReg1 and cmpOp2(imm or reg) while building
          // new value jump instruction.
          cmpReg1 = MI.getOperand(1).getReg();
          if (MI.getOperand(1).isKill())
            MO1IsKill = true;

          if (isSecondOpReg) {
            cmpOp2 = MI.getOperand(2).getReg();
            if (MI.getOperand(2).isKill())
              MO2IsKill = true;
          } else
            cmpOp2 = MI.getOperand(2).getImm();
          continue;
        }
      }

      if (foundCompare && foundJump) {

        // If "common" checks fail, bail out on this BB.
        if (!commonChecksToProhibitNewValueJump(afterRA, MII))
          break;

        bool foundFeeder = false;
        MachineBasicBlock::iterator feederPos = MII;
        if (MI.getOperand(0).isReg() && MI.getOperand(0).isDef() &&
            (MI.getOperand(0).getReg() == cmpReg1 ||
             (isSecondOpReg &&
              MI.getOperand(0).getReg() == (unsigned)cmpOp2))) {

          unsigned feederReg = MI.getOperand(0).getReg();

          // First try to see if we can get the feeder from the first operand
          // of the compare. If we can not, and if secondOpReg is true
          // (second operand of the compare is also register), try that one.
          // TODO: Try to come up with some heuristic to figure out which
          // feeder would benefit.

          if (feederReg == cmpReg1) {
            if (!canBeFeederToNewValueJump(QII, QRI, MII, jmpPos, cmpPos, MF)) {
              if (!isSecondOpReg)
                break;
              else
                continue;
            } else
              foundFeeder = true;
          }

          if (!foundFeeder &&
               isSecondOpReg &&
               feederReg == (unsigned) cmpOp2)
            if (!canBeFeederToNewValueJump(QII, QRI, MII, jmpPos, cmpPos, MF))
              break;

          if (isSecondOpReg) {
            // In case of CMPLT, or CMPLTU, or EQ with the second register
            // to newify, swap the operands.
            if (cmpInstr->getOpcode() == Hexagon::C2_cmpeq &&
                                     feederReg == (unsigned) cmpOp2) {
              unsigned tmp = cmpReg1;
              bool tmpIsKill = MO1IsKill;
              cmpReg1 = cmpOp2;
              MO1IsKill = MO2IsKill;
              cmpOp2 = tmp;
              MO2IsKill = tmpIsKill;
            }

            // Now we have swapped the operands, all we need to check is,
            // if the second operand (after swap) is the feeder.
            // And if it is, make a note.
            if (feederReg == (unsigned)cmpOp2)
              isSecondOpNewified = true;
          }

          // Now that we are moving feeder close the jump,
          // make sure we are respecting the kill values of
          // the operands of the feeder.

          bool updatedIsKill = false;
          for (unsigned i = 0; i < MI.getNumOperands(); i++) {
            MachineOperand &MO = MI.getOperand(i);
            if (MO.isReg() && MO.isUse()) {
              unsigned feederReg = MO.getReg();
              for (MachineBasicBlock::iterator localII = feederPos,
                   end = jmpPos; localII != end; localII++) {
                MachineInstr &localMI = *localII;
                for (unsigned j = 0; j < localMI.getNumOperands(); j++) {
                  MachineOperand &localMO = localMI.getOperand(j);
                  if (localMO.isReg() && localMO.isUse() &&
                      localMO.isKill() && feederReg == localMO.getReg()) {
                    // We found that there is kill of a use register
                    // Set up a kill flag on the register
                    localMO.setIsKill(false);
                    MO.setIsKill();
                    updatedIsKill = true;
                    break;
                  }
                }
                if (updatedIsKill) break;
              }
            }
            if (updatedIsKill) break;
          }

          MBB->splice(jmpPos, MI.getParent(), MI);
          MBB->splice(jmpPos, MI.getParent(), cmpInstr);
          DebugLoc dl = MI.getDebugLoc();
          MachineInstr *NewMI;

          assert((isNewValueJumpCandidate(*cmpInstr)) &&
                 "This compare is not a New Value Jump candidate.");
          unsigned opc = getNewValueJumpOpcode(cmpInstr, cmpOp2,
                                               isSecondOpNewified,
                                               jmpTarget, MBPI);
          if (invertPredicate)
            opc = QII->getInvertedPredicatedOpcode(opc);

          if (isSecondOpReg)
            NewMI = BuildMI(*MBB, jmpPos, dl,
                                  QII->get(opc))
                                    .addReg(cmpReg1, getKillRegState(MO1IsKill))
                                    .addReg(cmpOp2, getKillRegState(MO2IsKill))
                                    .addMBB(jmpTarget);

          else if ((cmpInstr->getOpcode() == Hexagon::C2_cmpeqi ||
                    cmpInstr->getOpcode() == Hexagon::C2_cmpgti) &&
                    cmpOp2 == -1 )
            // Corresponding new-value compare jump instructions don't have the
            // operand for -1 immediate value.
            NewMI = BuildMI(*MBB, jmpPos, dl,
                                  QII->get(opc))
                                    .addReg(cmpReg1, getKillRegState(MO1IsKill))
                                    .addMBB(jmpTarget);

          else
            NewMI = BuildMI(*MBB, jmpPos, dl,
                                  QII->get(opc))
                                    .addReg(cmpReg1, getKillRegState(MO1IsKill))
                                    .addImm(cmpOp2)
                                    .addMBB(jmpTarget);

          assert(NewMI && "New Value Jump Instruction Not created!");
          (void)NewMI;
          if (cmpInstr->getOperand(0).isReg() &&
              cmpInstr->getOperand(0).isKill())
            cmpInstr->getOperand(0).setIsKill(false);
          if (cmpInstr->getOperand(1).isReg() &&
              cmpInstr->getOperand(1).isKill())
            cmpInstr->getOperand(1).setIsKill(false);
          cmpInstr->eraseFromParent();
          jmpInstr->eraseFromParent();
          ++nvjGenerated;
          ++NumNVJGenerated;
          break;
        }
      }
    }
  }

  return true;

}
Exemple #22
0
bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
  DEBUG(dbgs() << "********** Register Stackifying **********\n"
                  "********** Function: "
               << MF.getName() << '\n');

  bool Changed = false;
  MachineRegisterInfo &MRI = MF.getRegInfo();
  WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
  AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();

  assert(MRI.isSSA() && "RegStackify depends on SSA form");

  // Walk the instructions from the bottom up. Currently we don't look past
  // block boundaries, and the blocks aren't ordered so the block visitation
  // order isn't significant, but we may want to change this in the future.
  for (MachineBasicBlock &MBB : MF) {
    for (MachineInstr &MI : reverse(MBB)) {
      MachineInstr *Insert = &MI;
      // Don't nest anything inside a phi.
      if (Insert->getOpcode() == TargetOpcode::PHI)
        break;

      // Don't nest anything inside an inline asm, because we don't have
      // constraints for $push inputs.
      if (Insert->getOpcode() == TargetOpcode::INLINEASM)
        break;

      // Iterate through the inputs in reverse order, since we'll be pulling
      // operands off the stack in LIFO order.
      bool AnyStackified = false;
      for (MachineOperand &Op : reverse(Insert->uses())) {
        // We're only interested in explicit virtual register operands.
        if (!Op.isReg() || Op.isImplicit() || !Op.isUse())
          continue;

        unsigned Reg = Op.getReg();
        if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
          // An instruction with a physical register. Conservatively mark it as
          // an expression stack input so that it isn't reordered with anything
          // in an expression stack which might use it (physical registers
          // aren't in SSA form so it's not trivial to determine this).
          // TODO: Be less conservative.
          ImposeStackInputOrdering(Insert);
          continue;
        }

        // Only consider registers with a single definition.
        // TODO: Eventually we may relax this, to stackify phi transfers.
        MachineInstr *Def = MRI.getVRegDef(Reg);
        if (!Def)
          continue;

        // There's no use in nesting implicit defs inside anything.
        if (Def->getOpcode() == TargetOpcode::IMPLICIT_DEF)
          continue;

        // Don't nest an INLINE_ASM def into anything, because we don't have
        // constraints for $pop outputs.
        if (Def->getOpcode() == TargetOpcode::INLINEASM)
          continue;

        // Don't nest PHIs inside of anything.
        if (Def->getOpcode() == TargetOpcode::PHI)
          continue;

        // Argument instructions represent live-in registers and not real
        // instructions.
        if (Def->getOpcode() == WebAssembly::ARGUMENT_I32 ||
            Def->getOpcode() == WebAssembly::ARGUMENT_I64 ||
            Def->getOpcode() == WebAssembly::ARGUMENT_F32 ||
            Def->getOpcode() == WebAssembly::ARGUMENT_F64)
          continue;

        // Single-use expression trees require defs that have one use.
        // TODO: Eventually we'll relax this, to take advantage of set_local
        // returning its result.
        if (!MRI.hasOneUse(Reg))
          continue;

        // For now, be conservative and don't look across block boundaries.
        // TODO: Be more aggressive.
        if (Def->getParent() != &MBB)
          continue;

        // Don't move instructions that have side effects or memory dependencies
        // or other complications.
        if (!IsSafeToMove(Def, Insert, AA))
          continue;

        Changed = true;
        AnyStackified = true;
        // Move the def down and nest it in the current instruction.
        MBB.insert(MachineBasicBlock::instr_iterator(Insert),
                   Def->removeFromParent());
        MFI.stackifyVReg(Reg);
        ImposeStackOrdering(Def, MRI);
        Insert = Def;
      }
      if (AnyStackified)
        ImposeStackOrdering(&MI, MRI);
    }
  }

  // If we used EXPR_STACK anywhere, add it to the live-in sets everywhere
  // so that it never looks like a use-before-def.
  if (Changed) {
    MF.getRegInfo().addLiveIn(WebAssembly::EXPR_STACK);
    for (MachineBasicBlock &MBB : MF)
      MBB.addLiveIn(WebAssembly::EXPR_STACK);
  }

#ifndef NDEBUG
  // Verify that pushes and pops are performed in FIFO order.
  SmallVector<unsigned, 0> Stack;
  for (MachineBasicBlock &MBB : MF) {
    for (MachineInstr &MI : MBB) {
      for (MachineOperand &MO : reverse(MI.explicit_operands())) {
        if (!MO.isReg())
          continue;
        unsigned VReg = MO.getReg();

        // Don't stackify physregs like SP or FP.
        if (!TargetRegisterInfo::isVirtualRegister(VReg))
          continue;

        if (MFI.isVRegStackified(VReg)) {
          if (MO.isDef())
            Stack.push_back(VReg);
          else
            assert(Stack.pop_back_val() == VReg);
        }
      }
    }
    // TODO: Generalize this code to support keeping values on the stack across
    // basic block boundaries.
    assert(Stack.empty());
  }
#endif

  return Changed;
}
Exemple #23
0
/// Insert epilog code into the function.
/// For ARC, this inserts a call to a function that restores callee saved
/// registers onto the stack, when enough callee saved registers are required.
void ARCFrameLowering::emitEpilogue(MachineFunction &MF,
                                    MachineBasicBlock &MBB) const {
  LLVM_DEBUG(dbgs() << "Emit Epilogue: " << MF.getName() << "\n");
  auto *AFI = MF.getInfo<ARCFunctionInfo>();
  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
  MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  uint64_t StackSize = MF.getFrameInfo().getStackSize();
  bool SavedBlink = false;
  unsigned AmountAboveFunclet = 0;
  // If we have variable sized frame objects, then we have to move
  // the stack pointer to a known spot (fp - StackSize).
  // Then, replace the frame pointer by (new) [sp,StackSize-4].
  // Then, move the stack pointer the rest of the way (sp = sp + StackSize).
  if (hasFP(MF)) {
    BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARC::SUB_rru6), ARC::SP)
        .addReg(ARC::FP)
        .addImm(StackSize);
    AmountAboveFunclet += 4;
  }

  // Now, move the stack pointer to the bottom of the save area for the funclet.
  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
  unsigned Last = determineLastCalleeSave(CSI);
  unsigned StackSlotsUsedByFunclet = 0;
  // Now, restore the callee save registers.
  if (UseSaveRestoreFunclet && Last > ARC::R14) {
    // BL to __ld_r13_to_<TRI->getRegAsmName()>
    StackSlotsUsedByFunclet = Last - ARC::R12;
    AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1);
    SavedBlink = true;
  }

  if (MFI.hasCalls() && !SavedBlink) {
    AmountAboveFunclet += 4;
    SavedBlink = true;
  }

  // Move the stack pointer up to the point of the funclet.
  if (StackSize - AmountAboveFunclet) {
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(StackSize - AmountAboveFunclet);
  }

  if (StackSlotsUsedByFunclet) {
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL))
        .addExternalSymbol(load_funclet_name[Last - ARC::R15])
        .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(4 * (StackSlotsUsedByFunclet));
  }
  // Now, pop blink if necessary.
  if (SavedBlink) {
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK));
  }
  // Now, pop fp if necessary.
  if (hasFP(MF)) {
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9))
        .addReg(ARC::SP, RegState::Define)
        .addReg(ARC::FP, RegState::Define)
        .addReg(ARC::SP)
        .addImm(4);
  }

  // Relieve the varargs area if necessary.
  if (MF.getFunction().isVarArg()) {
    // Add in the varargs area here first.
    LLVM_DEBUG(dbgs() << "Varargs\n");
    unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(VarArgsBytes);
  }
}
Exemple #24
0
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
  auto It = Functions.find(MF.getName());
  if (It == Functions.end())
    return error(Twine("no machine function information for function '") +
                 MF.getName() + "' in the MIR file");
  // TODO: Recreate the machine function.
  const yaml::MachineFunction &YamlMF = *It->getValue();
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);
  MF.setHasInlineAsm(YamlMF.HasInlineAsm);
  PerFunctionMIParsingState PFS;
  if (initializeRegisterInfo(MF, YamlMF, PFS))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(*ConstantPool, YamlMF, MF,
                               PFS.ConstantPoolSlots))
      return true;
  }

  const auto &F = *MF.getFunction();
  for (const auto &YamlMBB : YamlMF.BasicBlocks) {
    const BasicBlock *BB = nullptr;
    const yaml::StringValue &Name = YamlMBB.Name;
    const yaml::StringValue &IRBlock = YamlMBB.IRBlock;
    if (!Name.Value.empty()) {
      BB = dyn_cast_or_null<BasicBlock>(
          F.getValueSymbolTable().lookup(Name.Value));
      if (!BB)
        return error(Name.SourceRange.Start,
                     Twine("basic block '") + Name.Value +
                         "' is not defined in the function '" + MF.getName() +
                         "'");
    }
    if (!IRBlock.Value.empty()) {
      // TODO: Report an error when both name and ir block are specified.
      SMDiagnostic Error;
      if (parseIRBlockReference(BB, SM, MF, IRBlock.Value, PFS, IRSlots, Error))
        return error(Error, IRBlock.SourceRange);
    }
    auto *MBB = MF.CreateMachineBasicBlock(BB);
    MF.insert(MF.end(), MBB);
    bool WasInserted =
        PFS.MBBSlots.insert(std::make_pair(YamlMBB.ID, MBB)).second;
    if (!WasInserted)
      return error(Twine("redefinition of machine basic block with id #") +
                   Twine(YamlMBB.ID));
  }

  if (YamlMF.BasicBlocks.empty())
    return error(Twine("machine function '") + Twine(MF.getName()) +
                 "' requires at least one machine basic block in its body");
  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(MF, YamlMF, PFS))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(MF, YamlMF.JumpTableInfo, PFS))
    return true;
  // Initialize the machine basic blocks after creating them all so that the
  // machine instructions parser can resolve the MBB references.
  unsigned I = 0;
  for (const auto &YamlMBB : YamlMF.BasicBlocks) {
    if (initializeMachineBasicBlock(MF, *MF.getBlockNumbered(I++), YamlMBB,
                                    PFS))
      return true;
  }
  // FIXME: This is a temporary workaround until the reserved registers can be
  // serialized.
  MF.getRegInfo().freezeReservedRegs(MF);
  MF.verify();
  return false;
}
bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) {
  LiveIntervals &LIS = getAnalysis<LiveIntervals>();
  MachineBlockFrequencyInfo &MBFI =
    getAnalysis<MachineBlockFrequencyInfo>();

  calculateSpillWeightsAndHints(LIS, MF, getAnalysis<MachineLoopInfo>(), MBFI);

  VirtRegMap &VRM = getAnalysis<VirtRegMap>();

  std::unique_ptr<Spiller> VRegSpiller(createInlineSpiller(*this, MF, VRM));

  MF.getRegInfo().freezeReservedRegs(MF);

  DEBUG(dbgs() << "PBQP Register Allocating for " << MF.getName() << "\n");

  // Allocator main loop:
  //
  // * Map current regalloc problem to a PBQP problem
  // * Solve the PBQP problem
  // * Map the solution back to a register allocation
  // * Spill if necessary
  //
  // This process is continued till no more spills are generated.

  // Find the vreg intervals in need of allocation.
  findVRegIntervalsToAlloc(MF, LIS);

#ifndef NDEBUG
  const Function &F = *MF.getFunction();
  std::string FullyQualifiedName =
    F.getParent()->getModuleIdentifier() + "." + F.getName().str();
#endif

  // If there are non-empty intervals allocate them using pbqp.
  if (!VRegsToAlloc.empty()) {

    const TargetSubtargetInfo &Subtarget = *MF.getTarget().getSubtargetImpl();
    std::unique_ptr<PBQPRAConstraintList> ConstraintsRoot =
      llvm::make_unique<PBQPRAConstraintList>();
    ConstraintsRoot->addConstraint(llvm::make_unique<SpillCosts>());
    ConstraintsRoot->addConstraint(llvm::make_unique<Interference>());
    if (PBQPCoalescing)
      ConstraintsRoot->addConstraint(llvm::make_unique<Coalescing>());
    ConstraintsRoot->addConstraint(Subtarget.getCustomPBQPConstraints());

    bool PBQPAllocComplete = false;
    unsigned Round = 0;

    while (!PBQPAllocComplete) {
      DEBUG(dbgs() << "  PBQP Regalloc round " << Round << ":\n");

      PBQPRAGraph G(PBQPRAGraph::GraphMetadata(MF, LIS, MBFI));
      initializeGraph(G);
      ConstraintsRoot->apply(G);

#ifndef NDEBUG
      if (PBQPDumpGraphs) {
        std::ostringstream RS;
        RS << Round;
        std::string GraphFileName = FullyQualifiedName + "." + RS.str() +
                                    ".pbqpgraph";
        std::error_code EC;
        raw_fd_ostream OS(GraphFileName, EC, sys::fs::F_Text);
        DEBUG(dbgs() << "Dumping graph for round " << Round << " to \""
              << GraphFileName << "\"\n");
        G.dumpToStream(OS);
      }
#endif

      PBQP::Solution Solution = PBQP::RegAlloc::solve(G);
      PBQPAllocComplete = mapPBQPToRegAlloc(G, Solution, VRM, *VRegSpiller);
      ++Round;
    }
  }

  // Finalise allocation, allocate empty ranges.
  finalizeAlloc(MF, LIS, VRM);
  VRegsToAlloc.clear();
  EmptyIntervalVRegs.clear();

  DEBUG(dbgs() << "Post alloc VirtRegMap:\n" << VRM << "\n");

  return true;
}
bool WebAssemblyLowerBrUnless::runOnMachineFunction(MachineFunction &MF) {
  DEBUG(dbgs() << "********** Lowering br_unless **********\n"
                  "********** Function: "
               << MF.getName() << '\n');

  auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
  const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
  auto &MRI = MF.getRegInfo();

  for (auto &MBB : MF) {
    for (auto MII = MBB.begin(); MII != MBB.end();) {
      MachineInstr *MI = &*MII++;
      if (MI->getOpcode() != WebAssembly::BR_UNLESS)
        continue;

      unsigned Cond = MI->getOperand(1).getReg();
      bool Inverted = false;

      // Attempt to invert the condition in place.
      if (MFI.isVRegStackified(Cond)) {
        assert(MRI.hasOneDef(Cond));
        MachineInstr *Def = MRI.getVRegDef(Cond);
        switch (Def->getOpcode()) {
          using namespace WebAssembly;
        case EQ_I32: Def->setDesc(TII.get(NE_I32)); Inverted = true; break;
        case NE_I32: Def->setDesc(TII.get(EQ_I32)); Inverted = true; break;
        case GT_S_I32: Def->setDesc(TII.get(LE_S_I32)); Inverted = true; break;
        case GE_S_I32: Def->setDesc(TII.get(LT_S_I32)); Inverted = true; break;
        case LT_S_I32: Def->setDesc(TII.get(GE_S_I32)); Inverted = true; break;
        case LE_S_I32: Def->setDesc(TII.get(GT_S_I32)); Inverted = true; break;
        case GT_U_I32: Def->setDesc(TII.get(LE_U_I32)); Inverted = true; break;
        case GE_U_I32: Def->setDesc(TII.get(LT_U_I32)); Inverted = true; break;
        case LT_U_I32: Def->setDesc(TII.get(GE_U_I32)); Inverted = true; break;
        case LE_U_I32: Def->setDesc(TII.get(GT_U_I32)); Inverted = true; break;
        case EQ_I64: Def->setDesc(TII.get(NE_I64)); Inverted = true; break;
        case NE_I64: Def->setDesc(TII.get(EQ_I64)); Inverted = true; break;
        case GT_S_I64: Def->setDesc(TII.get(LE_S_I64)); Inverted = true; break;
        case GE_S_I64: Def->setDesc(TII.get(LT_S_I64)); Inverted = true; break;
        case LT_S_I64: Def->setDesc(TII.get(GE_S_I64)); Inverted = true; break;
        case LE_S_I64: Def->setDesc(TII.get(GT_S_I64)); Inverted = true; break;
        case GT_U_I64: Def->setDesc(TII.get(LE_U_I64)); Inverted = true; break;
        case GE_U_I64: Def->setDesc(TII.get(LT_U_I64)); Inverted = true; break;
        case LT_U_I64: Def->setDesc(TII.get(GE_U_I64)); Inverted = true; break;
        case LE_U_I64: Def->setDesc(TII.get(GT_U_I64)); Inverted = true; break;
        case EQ_F32: Def->setDesc(TII.get(NE_F32)); Inverted = true; break;
        case NE_F32: Def->setDesc(TII.get(EQ_F32)); Inverted = true; break;
        case EQ_F64: Def->setDesc(TII.get(NE_F64)); Inverted = true; break;
        case NE_F64: Def->setDesc(TII.get(EQ_F64)); Inverted = true; break;
        default: break;
        }
      }

      // If we weren't able to invert the condition in place. Insert an
      // expression to invert it.
      if (!Inverted) {
        unsigned Tmp = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
        MFI.stackifyVReg(Tmp);
        BuildMI(MBB, MI, MI->getDebugLoc(), TII.get(WebAssembly::EQZ_I32), Tmp)
            .addReg(Cond);
        Cond = Tmp;
        Inverted = true;
      }

      // The br_unless condition has now been inverted. Insert a br_if and
      // delete the br_unless.
      assert(Inverted);
      BuildMI(MBB, MI, MI->getDebugLoc(), TII.get(WebAssembly::BR_IF))
          .addOperand(MI->getOperand(0))
          .addReg(Cond);
      MBB.erase(MI);
    }
  }

  return true;
}
/// runOnMachineFunction - Insert prolog/epilog code and replace abstract
/// frame indexes with appropriate references.
///
bool PEI::runOnMachineFunction(MachineFunction &Fn) {
  const Function* F = Fn.getFunction();
  const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
  const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();

  assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs");

  RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL;
  FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);

  // Calculate the MaxCallFrameSize and AdjustsStack variables for the
  // function's frame information. Also eliminates call frame pseudo
  // instructions.
  calculateCallsInformation(Fn);

  // Allow the target machine to make some adjustments to the function
  // e.g. UsedPhysRegs before calculateCalleeSavedRegisters.
  TFI->processFunctionBeforeCalleeSavedScan(Fn, RS);

  // Scan the function for modified callee saved registers and insert spill code
  // for any callee saved registers that are modified.
  calculateCalleeSavedRegisters(Fn);

  // Determine placement of CSR spill/restore code:
  //  - With shrink wrapping, place spills and restores to tightly
  //    enclose regions in the Machine CFG of the function where
  //    they are used.
  //  - Without shink wrapping (default), place all spills in the
  //    entry block, all restores in return blocks.
  placeCSRSpillsAndRestores(Fn);

  // Add the code to save and restore the callee saved registers
  if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
                                       Attribute::Naked))
    insertCSRSpillsAndRestores(Fn);

  // Allow the target machine to make final modifications to the function
  // before the frame layout is finalized.
  TFI->processFunctionBeforeFrameFinalized(Fn, RS);

  // Calculate actual frame offsets for all abstract stack objects...
  calculateFrameObjectOffsets(Fn);

  // Add prolog and epilog code to the function.  This function is required
  // to align the stack frame as necessary for any stack variables or
  // called functions.  Because of this, calculateCalleeSavedRegisters()
  // must be called before this function in order to set the AdjustsStack
  // and MaxCallFrameSize variables.
  if (!F->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
                                       Attribute::Naked))
    insertPrologEpilogCode(Fn);

  // Replace all MO_FrameIndex operands with physical register references
  // and actual offsets.
  //
  replaceFrameIndices(Fn);

  // If register scavenging is needed, as we've enabled doing it as a
  // post-pass, scavenge the virtual registers that frame index elimiation
  // inserted.
  if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging)
    scavengeFrameVirtualRegs(Fn);

  // Clear any vregs created by virtual scavenging.
  Fn.getRegInfo().clearVirtRegs();

  // Warn on stack size when we exceeds the given limit.
  MachineFrameInfo *MFI = Fn.getFrameInfo();
  if (WarnStackSize.getNumOccurrences() > 0 &&
      WarnStackSize < MFI->getStackSize())
    errs() << "warning: Stack size limit exceeded (" << MFI->getStackSize()
           << ") in " << Fn.getName()  << ".\n";

  delete RS;
  clearAllSets();
  return true;
}
Exemple #28
0
bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) {
  if (skipFunction(MF.getFunction()) || MF.empty() || !isShrinkWrapEnabled(MF))
    return false;

  LLVM_DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n');

  init(MF);

  ReversePostOrderTraversal<MachineBasicBlock *> RPOT(&*MF.begin());
  if (containsIrreducibleCFG<MachineBasicBlock *>(RPOT, *MLI)) {
    // If MF is irreducible, a block may be in a loop without
    // MachineLoopInfo reporting it. I.e., we may use the
    // post-dominance property in loops, which lead to incorrect
    // results. Moreover, we may miss that the prologue and
    // epilogue are not in the same loop, leading to unbalanced
    // construction/deconstruction of the stack frame.
    LLVM_DEBUG(dbgs() << "Irreducible CFGs are not supported yet\n");
    return false;
  }

  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
  std::unique_ptr<RegScavenger> RS(
      TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr);

  for (MachineBasicBlock &MBB : MF) {
    LLVM_DEBUG(dbgs() << "Look into: " << MBB.getNumber() << ' '
                      << MBB.getName() << '\n');

    if (MBB.isEHFuncletEntry()) {
      LLVM_DEBUG(dbgs() << "EH Funclets are not supported yet.\n");
      return false;
    }

    if (MBB.isEHPad()) {
      // Push the prologue and epilogue outside of
      // the region that may throw by making sure
      // that all the landing pads are at least at the
      // boundary of the save and restore points.
      // The problem with exceptions is that the throw
      // is not properly modeled and in particular, a
      // basic block can jump out from the middle.
      updateSaveRestorePoints(MBB, RS.get());
      if (!ArePointsInteresting()) {
        LLVM_DEBUG(dbgs() << "EHPad prevents shrink-wrapping\n");
        return false;
      }
      continue;
    }

    for (const MachineInstr &MI : MBB) {
      if (!useOrDefCSROrFI(MI, RS.get()))
        continue;
      // Save (resp. restore) point must dominate (resp. post dominate)
      // MI. Look for the proper basic block for those.
      updateSaveRestorePoints(MBB, RS.get());
      // If we are at a point where we cannot improve the placement of
      // save/restore instructions, just give up.
      if (!ArePointsInteresting()) {
        LLVM_DEBUG(dbgs() << "No Shrink wrap candidate found\n");
        return false;
      }
      // No need to look for other instructions, this basic block
      // will already be part of the handled region.
      break;
    }
  }
  if (!ArePointsInteresting()) {
    // If the points are not interesting at this point, then they must be null
    // because it means we did not encounter any frame/CSR related code.
    // Otherwise, we would have returned from the previous loop.
    assert(!Save && !Restore && "We miss a shrink-wrap opportunity?!");
    LLVM_DEBUG(dbgs() << "Nothing to shrink-wrap\n");
    return false;
  }

  LLVM_DEBUG(dbgs() << "\n ** Results **\nFrequency of the Entry: " << EntryFreq
                    << '\n');

  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
  do {
    LLVM_DEBUG(dbgs() << "Shrink wrap candidates (#, Name, Freq):\nSave: "
                      << Save->getNumber() << ' ' << Save->getName() << ' '
                      << MBFI->getBlockFreq(Save).getFrequency()
                      << "\nRestore: " << Restore->getNumber() << ' '
                      << Restore->getName() << ' '
                      << MBFI->getBlockFreq(Restore).getFrequency() << '\n');

    bool IsSaveCheap, TargetCanUseSaveAsPrologue = false;
    if (((IsSaveCheap = EntryFreq >= MBFI->getBlockFreq(Save).getFrequency()) &&
         EntryFreq >= MBFI->getBlockFreq(Restore).getFrequency()) &&
        ((TargetCanUseSaveAsPrologue = TFI->canUseAsPrologue(*Save)) &&
         TFI->canUseAsEpilogue(*Restore)))
      break;
    LLVM_DEBUG(
        dbgs() << "New points are too expensive or invalid for the target\n");
    MachineBasicBlock *NewBB;
    if (!IsSaveCheap || !TargetCanUseSaveAsPrologue) {
      Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
      if (!Save)
        break;
      NewBB = Save;
    } else {
      // Restore is expensive.
      Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT);
      if (!Restore)
        break;
      NewBB = Restore;
    }
    updateSaveRestorePoints(*NewBB, RS.get());
  } while (Save && Restore);

  if (!ArePointsInteresting()) {
    ++NumCandidatesDropped;
    return false;
  }

  LLVM_DEBUG(dbgs() << "Final shrink wrap candidates:\nSave: "
                    << Save->getNumber() << ' ' << Save->getName()
                    << "\nRestore: " << Restore->getNumber() << ' '
                    << Restore->getName() << '\n');

  MachineFrameInfo &MFI = MF.getFrameInfo();
  MFI.setSavePoint(Save);
  MFI.setRestorePoint(Restore);
  ++NumCandidates;
  return false;
}
bool AArch64ConditionOptimizer::runOnMachineFunction(MachineFunction &MF) {
  DEBUG(dbgs() << "********** AArch64 Conditional Compares **********\n"
               << "********** Function: " << MF.getName() << '\n');
  TII = MF.getSubtarget().getInstrInfo();
  DomTree = &getAnalysis<MachineDominatorTree>();
  MRI = &MF.getRegInfo();

  bool Changed = false;

  // Visit blocks in dominator tree pre-order. The pre-order enables multiple
  // cmp-conversions from the same head block.
  // Note that updateDomTree() modifies the children of the DomTree node
  // currently being visited. The df_iterator supports that; it doesn't look at
  // child_begin() / child_end() until after a node has been visited.
  for (MachineDomTreeNode *I : depth_first(DomTree)) {
    MachineBasicBlock *HBB = I->getBlock();

    SmallVector<MachineOperand, 4> HeadCond;
    MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
    if (TII->AnalyzeBranch(*HBB, TBB, FBB, HeadCond)) {
      continue;
    }

    // Equivalence check is to skip loops.
    if (!TBB || TBB == HBB) {
      continue;
    }

    SmallVector<MachineOperand, 4> TrueCond;
    MachineBasicBlock *TBB_TBB = nullptr, *TBB_FBB = nullptr;
    if (TII->AnalyzeBranch(*TBB, TBB_TBB, TBB_FBB, TrueCond)) {
      continue;
    }

    MachineInstr *HeadCmpMI = findSuitableCompare(HBB);
    if (!HeadCmpMI) {
      continue;
    }

    MachineInstr *TrueCmpMI = findSuitableCompare(TBB);
    if (!TrueCmpMI) {
      continue;
    }

    AArch64CC::CondCode HeadCmp;
    if (HeadCond.empty() || !parseCond(HeadCond, HeadCmp)) {
      continue;
    }

    AArch64CC::CondCode TrueCmp;
    if (TrueCond.empty() || !parseCond(TrueCond, TrueCmp)) {
      continue;
    }

    const int HeadImm = (int)HeadCmpMI->getOperand(2).getImm();
    const int TrueImm = (int)TrueCmpMI->getOperand(2).getImm();

    DEBUG(dbgs() << "Head branch:\n");
    DEBUG(dbgs() << "\tcondition: "
          << AArch64CC::getCondCodeName(HeadCmp) << '\n');
    DEBUG(dbgs() << "\timmediate: " << HeadImm << '\n');

    DEBUG(dbgs() << "True branch:\n");
    DEBUG(dbgs() << "\tcondition: "
          << AArch64CC::getCondCodeName(TrueCmp) << '\n');
    DEBUG(dbgs() << "\timmediate: " << TrueImm << '\n');

    if (((HeadCmp == AArch64CC::GT && TrueCmp == AArch64CC::LT) ||
         (HeadCmp == AArch64CC::LT && TrueCmp == AArch64CC::GT)) &&
        std::abs(TrueImm - HeadImm) == 2) {
      // This branch transforms machine instructions that correspond to
      //
      // 1) (a > {TrueImm} && ...) || (a < {HeadImm} && ...)
      // 2) (a < {TrueImm} && ...) || (a > {HeadImm} && ...)
      //
      // into
      //
      // 1) (a >= {NewImm} && ...) || (a <= {NewImm} && ...)
      // 2) (a <= {NewImm} && ...) || (a >= {NewImm} && ...)

      CmpInfo HeadCmpInfo = adjustCmp(HeadCmpMI, HeadCmp);
      CmpInfo TrueCmpInfo = adjustCmp(TrueCmpMI, TrueCmp);
      if (std::get<0>(HeadCmpInfo) == std::get<0>(TrueCmpInfo) &&
          std::get<1>(HeadCmpInfo) == std::get<1>(TrueCmpInfo)) {
        modifyCmp(HeadCmpMI, HeadCmpInfo);
        modifyCmp(TrueCmpMI, TrueCmpInfo);
        Changed = true;
      }
    } else if (((HeadCmp == AArch64CC::GT && TrueCmp == AArch64CC::GT) ||
                (HeadCmp == AArch64CC::LT && TrueCmp == AArch64CC::LT)) &&
                std::abs(TrueImm - HeadImm) == 1) {
      // This branch transforms machine instructions that correspond to
      //
      // 1) (a > {TrueImm} && ...) || (a > {HeadImm} && ...)
      // 2) (a < {TrueImm} && ...) || (a < {HeadImm} && ...)
      //
      // into
      //
      // 1) (a <= {NewImm} && ...) || (a >  {NewImm} && ...)
      // 2) (a <  {NewImm} && ...) || (a >= {NewImm} && ...)

      // GT -> GE transformation increases immediate value, so picking the
      // smaller one; LT -> LE decreases immediate value so invert the choice.
      bool adjustHeadCond = (HeadImm < TrueImm);
      if (HeadCmp == AArch64CC::LT) {
          adjustHeadCond = !adjustHeadCond;
      }

      if (adjustHeadCond) {
        Changed |= adjustTo(HeadCmpMI, HeadCmp, TrueCmpMI, TrueImm);
      } else {
        Changed |= adjustTo(TrueCmpMI, TrueCmp, HeadCmpMI, HeadImm);
      }
    }
    // Other transformation cases almost never occur due to generation of < or >
    // comparisons instead of <= and >=.
  }

  return Changed;
}
Exemple #30
0
/// Insert prolog code into the function.
/// For ARC, this inserts a call to a function that puts required callee saved
/// registers onto the stack, when enough callee saved registers are required.
void ARCFrameLowering::emitPrologue(MachineFunction &MF,
                                    MachineBasicBlock &MBB) const {
  LLVM_DEBUG(dbgs() << "Emit Prologue: " << MF.getName() << "\n");
  auto *AFI = MF.getInfo<ARCFunctionInfo>();
  MachineModuleInfo &MMI = MF.getMMI();
  MCContext &Context = MMI.getContext();
  const MCRegisterInfo *MRI = Context.getRegisterInfo();
  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
  MachineBasicBlock::iterator MBBI = MBB.begin();
  // Debug location must be unknown since the first debug location is used
  // to determine the end of the prologue.
  DebugLoc dl;
  MachineFrameInfo &MFI = MF.getFrameInfo();
  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
  unsigned Last = determineLastCalleeSave(CSI);
  unsigned StackSlotsUsedByFunclet = 0;
  bool SavedBlink = false;
  unsigned AlreadyAdjusted = 0;
  if (MF.getFunction().isVarArg()) {
    // Add in the varargs area here first.
    LLVM_DEBUG(dbgs() << "Varargs\n");
    unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
    BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(VarArgsBytes);
  }
  if (hasFP(MF)) {
    LLVM_DEBUG(dbgs() << "Saving FP\n");
    BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9))
        .addReg(ARC::SP, RegState::Define)
        .addReg(ARC::FP)
        .addReg(ARC::SP)
        .addImm(-4);
    AlreadyAdjusted += 4;
  }
  if (UseSaveRestoreFunclet && Last > ARC::R14) {
    LLVM_DEBUG(dbgs() << "Creating store funclet.\n");
    // BL to __save_r13_to_<TRI->getRegAsmName()>
    StackSlotsUsedByFunclet = Last - ARC::R12;
    BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
    BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(4 * StackSlotsUsedByFunclet);
    BuildMI(MBB, MBBI, dl, TII->get(ARC::BL))
        .addExternalSymbol(store_funclet_name[Last - ARC::R15])
        .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
    AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1);
    SavedBlink = true;
  }
  // If we haven't saved BLINK, but we need to...do that now.
  if (MFI.hasCalls() && !SavedBlink) {
    LLVM_DEBUG(dbgs() << "Creating save blink.\n");
    BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
    AlreadyAdjusted += 4;
  }
  if (AFI->MaxCallStackReq > 0)
    MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq);
  // We have already saved some of the stack...
  LLVM_DEBUG(dbgs() << "Adjusting stack by: "
                    << (MFI.getStackSize() - AlreadyAdjusted) << "\n");
  generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl,
                          -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP);

  if (hasFP(MF)) {
    LLVM_DEBUG(dbgs() << "Setting FP from SP.\n");
    BuildMI(MBB, MBBI, dl,
            TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6
                                                   : ARC::ADD_rrlimm),
            ARC::FP)
        .addReg(ARC::SP)
        .addImm(MFI.getStackSize());
  }

  // Emit CFI records:
  // .cfi_def_cfa_offset StackSize
  // .cfi_offset fp, -StackSize
  // .cfi_offset blink, -StackSize+4
  unsigned CFIIndex = MF.addFrameInst(
      MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize()));
  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
      .addCFIIndex(CFIIndex)
      .setMIFlags(MachineInstr::FrameSetup);

  int CurOffset = -4;
  if (hasFP(MF)) {
    CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
        nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset));
    BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex)
        .setMIFlags(MachineInstr::FrameSetup);
    CurOffset -= 4;
  }

  if (MFI.hasCalls()) {
    CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
        nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset));
    BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex)
        .setMIFlags(MachineInstr::FrameSetup);
  }
  // CFI for the rest of the registers.
  for (const auto &Entry : CSI) {
    unsigned Reg = Entry.getReg();
    int FI = Entry.getFrameIdx();
    // Skip BLINK and FP.
    if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK))
      continue;
    CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
        nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI)));
    BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex)
        .setMIFlags(MachineInstr::FrameSetup);
  }
}