123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251 |
- //===-- SelectionDAGISel.cpp - Implement the SelectionDAGISel class -------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- //
- // This implements the SelectionDAGISel class.
- //
- //===----------------------------------------------------------------------===//
- #define DEBUG_TYPE "isel"
- #include "ScheduleDAGSDNodes.h"
- #include "SelectionDAGBuild.h"
- #include "llvm/CodeGen/SelectionDAGISel.h"
- #include "llvm/Analysis/AliasAnalysis.h"
- #include "llvm/Constants.h"
- #include "llvm/CallingConv.h"
- #include "llvm/DerivedTypes.h"
- #include "llvm/Function.h"
- #include "llvm/GlobalVariable.h"
- #include "llvm/InlineAsm.h"
- #include "llvm/Instructions.h"
- #include "llvm/Intrinsics.h"
- #include "llvm/IntrinsicInst.h"
- #include "llvm/CodeGen/FastISel.h"
- #include "llvm/CodeGen/GCStrategy.h"
- #include "llvm/CodeGen/GCMetadata.h"
- #include "llvm/CodeGen/MachineFunction.h"
- #include "llvm/CodeGen/MachineFunctionAnalysis.h"
- #include "llvm/CodeGen/MachineFrameInfo.h"
- #include "llvm/CodeGen/MachineInstrBuilder.h"
- #include "llvm/CodeGen/MachineJumpTableInfo.h"
- #include "llvm/CodeGen/MachineModuleInfo.h"
- #include "llvm/CodeGen/MachineRegisterInfo.h"
- #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
- #include "llvm/CodeGen/SchedulerRegistry.h"
- #include "llvm/CodeGen/SelectionDAG.h"
- #include "llvm/CodeGen/DwarfWriter.h"
- #include "llvm/Target/TargetRegisterInfo.h"
- #include "llvm/Target/TargetData.h"
- #include "llvm/Target/TargetFrameInfo.h"
- #include "llvm/Target/TargetInstrInfo.h"
- #include "llvm/Target/TargetLowering.h"
- #include "llvm/Target/TargetMachine.h"
- #include "llvm/Target/TargetOptions.h"
- #include "llvm/Support/Compiler.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/MathExtras.h"
- #include "llvm/Support/Timer.h"
- #include "llvm/Support/raw_ostream.h"
- #include <algorithm>
- using namespace llvm;
- static cl::opt<bool>
- DisableLegalizeTypes("disable-legalize-types", cl::Hidden);
- static cl::opt<bool>
- EnableFastISelVerbose("fast-isel-verbose", cl::Hidden,
- cl::desc("Enable verbose messages in the \"fast\" "
- "instruction selector"));
- static cl::opt<bool>
- EnableFastISelAbort("fast-isel-abort", cl::Hidden,
- cl::desc("Enable abort calls when \"fast\" instruction fails"));
- static cl::opt<bool>
- SchedLiveInCopies("schedule-livein-copies",
- cl::desc("Schedule copies of livein registers"),
- cl::init(false));
- #ifndef NDEBUG
- static cl::opt<bool>
- ViewDAGCombine1("view-dag-combine1-dags", cl::Hidden,
- cl::desc("Pop up a window to show dags before the first "
- "dag combine pass"));
- static cl::opt<bool>
- ViewLegalizeTypesDAGs("view-legalize-types-dags", cl::Hidden,
- cl::desc("Pop up a window to show dags before legalize types"));
- static cl::opt<bool>
- ViewLegalizeDAGs("view-legalize-dags", cl::Hidden,
- cl::desc("Pop up a window to show dags before legalize"));
- static cl::opt<bool>
- ViewDAGCombine2("view-dag-combine2-dags", cl::Hidden,
- cl::desc("Pop up a window to show dags before the second "
- "dag combine pass"));
- static cl::opt<bool>
- ViewDAGCombineLT("view-dag-combine-lt-dags", cl::Hidden,
- cl::desc("Pop up a window to show dags before the post legalize types"
- " dag combine pass"));
- static cl::opt<bool>
- ViewISelDAGs("view-isel-dags", cl::Hidden,
- cl::desc("Pop up a window to show isel dags as they are selected"));
- static cl::opt<bool>
- ViewSchedDAGs("view-sched-dags", cl::Hidden,
- cl::desc("Pop up a window to show sched dags as they are processed"));
- static cl::opt<bool>
- ViewSUnitDAGs("view-sunit-dags", cl::Hidden,
- cl::desc("Pop up a window to show SUnit dags after they are processed"));
- #else
- static const bool ViewDAGCombine1 = false,
- ViewLegalizeTypesDAGs = false, ViewLegalizeDAGs = false,
- ViewDAGCombine2 = false,
- ViewDAGCombineLT = false,
- ViewISelDAGs = false, ViewSchedDAGs = false,
- ViewSUnitDAGs = false;
- #endif
- //===---------------------------------------------------------------------===//
- ///
- /// RegisterScheduler class - Track the registration of instruction schedulers.
- ///
- //===---------------------------------------------------------------------===//
- MachinePassRegistry RegisterScheduler::Registry;
- //===---------------------------------------------------------------------===//
- ///
- /// ISHeuristic command line option for instruction schedulers.
- ///
- //===---------------------------------------------------------------------===//
- static cl::opt<RegisterScheduler::FunctionPassCtor, false,
- RegisterPassParser<RegisterScheduler> >
- ISHeuristic("pre-RA-sched",
- cl::init(&createDefaultScheduler),
- cl::desc("Instruction schedulers available (before register"
- " allocation):"));
- static RegisterScheduler
- defaultListDAGScheduler("default", "Best scheduler for the target",
- createDefaultScheduler);
- namespace llvm {
- //===--------------------------------------------------------------------===//
- /// createDefaultScheduler - This creates an instruction scheduler appropriate
- /// for the target.
- ScheduleDAGSDNodes* createDefaultScheduler(SelectionDAGISel *IS,
- CodeGenOpt::Level OptLevel) {
- const TargetLowering &TLI = IS->getTargetLowering();
- if (OptLevel == CodeGenOpt::None)
- return createFastDAGScheduler(IS, OptLevel);
- if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency)
- return createTDListDAGScheduler(IS, OptLevel);
- assert(TLI.getSchedulingPreference() ==
- TargetLowering::SchedulingForRegPressure && "Unknown sched type!");
- return createBURRListDAGScheduler(IS, OptLevel);
- }
- }
- // EmitInstrWithCustomInserter - This method should be implemented by targets
- // that mark instructions with the 'usesCustomDAGSchedInserter' flag. These
- // instructions are special in various ways, which require special support to
- // insert. The specified MachineInstr is created but not inserted into any
- // basic blocks, and the scheduler passes ownership of it to this method.
- MachineBasicBlock *TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
- MachineBasicBlock *MBB) const {
- #ifndef NDEBUG
- cerr << "If a target marks an instruction with "
- "'usesCustomDAGSchedInserter', it must implement "
- "TargetLowering::EmitInstrWithCustomInserter!";
- #endif
- llvm_unreachable(0);
- return 0;
- }
- /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
- /// physical register has only a single copy use, then coalesced the copy
- /// if possible.
- static void EmitLiveInCopy(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator &InsertPos,
- unsigned VirtReg, unsigned PhysReg,
- const TargetRegisterClass *RC,
- DenseMap<MachineInstr*, unsigned> &CopyRegMap,
- const MachineRegisterInfo &MRI,
- const TargetRegisterInfo &TRI,
- const TargetInstrInfo &TII) {
- unsigned NumUses = 0;
- MachineInstr *UseMI = NULL;
- for (MachineRegisterInfo::use_iterator UI = MRI.use_begin(VirtReg),
- UE = MRI.use_end(); UI != UE; ++UI) {
- UseMI = &*UI;
- if (++NumUses > 1)
- break;
- }
- // If the number of uses is not one, or the use is not a move instruction,
- // don't coalesce. Also, only coalesce away a virtual register to virtual
- // register copy.
- bool Coalesced = false;
- unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
- if (NumUses == 1 &&
- TII.isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
- TargetRegisterInfo::isVirtualRegister(DstReg)) {
- VirtReg = DstReg;
- Coalesced = true;
- }
- // Now find an ideal location to insert the copy.
- MachineBasicBlock::iterator Pos = InsertPos;
- while (Pos != MBB->begin()) {
- MachineInstr *PrevMI = prior(Pos);
- DenseMap<MachineInstr*, unsigned>::iterator RI = CopyRegMap.find(PrevMI);
- // copyRegToReg might emit multiple instructions to do a copy.
- unsigned CopyDstReg = (RI == CopyRegMap.end()) ? 0 : RI->second;
- if (CopyDstReg && !TRI.regsOverlap(CopyDstReg, PhysReg))
- // This is what the BB looks like right now:
- // r1024 = mov r0
- // ...
- // r1 = mov r1024
- //
- // We want to insert "r1025 = mov r1". Inserting this copy below the
- // move to r1024 makes it impossible for that move to be coalesced.
- //
- // r1025 = mov r1
- // r1024 = mov r0
- // ...
- // r1 = mov 1024
- // r2 = mov 1025
- break; // Woot! Found a good location.
- --Pos;
- }
- bool Emitted = TII.copyRegToReg(*MBB, Pos, VirtReg, PhysReg, RC, RC);
- assert(Emitted && "Unable to issue a live-in copy instruction!\n");
- (void) Emitted;
-
- CopyRegMap.insert(std::make_pair(prior(Pos), VirtReg));
- if (Coalesced) {
- if (&*InsertPos == UseMI) ++InsertPos;
- MBB->erase(UseMI);
- }
- }
- /// EmitLiveInCopies - If this is the first basic block in the function,
- /// and if it has live ins that need to be copied into vregs, emit the
- /// copies into the block.
- static void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
- const MachineRegisterInfo &MRI,
- const TargetRegisterInfo &TRI,
- const TargetInstrInfo &TII) {
- if (SchedLiveInCopies) {
- // Emit the copies at a heuristically-determined location in the block.
- DenseMap<MachineInstr*, unsigned> CopyRegMap;
- MachineBasicBlock::iterator InsertPos = EntryMBB->begin();
- for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
- E = MRI.livein_end(); LI != E; ++LI)
- if (LI->second) {
- const TargetRegisterClass *RC = MRI.getRegClass(LI->second);
- EmitLiveInCopy(EntryMBB, InsertPos, LI->second, LI->first,
- RC, CopyRegMap, MRI, TRI, TII);
- }
- } else {
- // Emit the copies into the top of the block.
- for (MachineRegisterInfo::livein_iterator LI = MRI.livein_begin(),
- E = MRI.livein_end(); LI != E; ++LI)
- if (LI->second) {
- const TargetRegisterClass *RC = MRI.getRegClass(LI->second);
- bool Emitted = TII.copyRegToReg(*EntryMBB, EntryMBB->begin(),
- LI->second, LI->first, RC, RC);
- assert(Emitted && "Unable to issue a live-in copy instruction!\n");
- (void) Emitted;
- }
- }
- }
- //===----------------------------------------------------------------------===//
- // SelectionDAGISel code
- //===----------------------------------------------------------------------===//
- SelectionDAGISel::SelectionDAGISel(TargetMachine &tm, CodeGenOpt::Level OL) :
- MachineFunctionPass(&ID), TM(tm), TLI(*tm.getTargetLowering()),
- FuncInfo(new FunctionLoweringInfo(TLI)),
- CurDAG(new SelectionDAG(TLI, *FuncInfo)),
- SDL(new SelectionDAGLowering(*CurDAG, TLI, *FuncInfo, OL)),
- GFI(),
- OptLevel(OL),
- DAGSize(0)
- {}
- SelectionDAGISel::~SelectionDAGISel() {
- delete SDL;
- delete CurDAG;
- delete FuncInfo;
- }
- unsigned SelectionDAGISel::MakeReg(EVT VT) {
- return RegInfo->createVirtualRegister(TLI.getRegClassFor(VT));
- }
- void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<AliasAnalysis>();
- AU.addPreserved<AliasAnalysis>();
- AU.addRequired<GCModuleInfo>();
- AU.addPreserved<GCModuleInfo>();
- AU.addRequired<DwarfWriter>();
- AU.addPreserved<DwarfWriter>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
- Function &Fn = *mf.getFunction();
- // Do some sanity-checking on the command-line options.
- assert((!EnableFastISelVerbose || EnableFastISel) &&
- "-fast-isel-verbose requires -fast-isel");
- assert((!EnableFastISelAbort || EnableFastISel) &&
- "-fast-isel-abort requires -fast-isel");
- // Get alias analysis for load/store combining.
- AA = &getAnalysis<AliasAnalysis>();
- MF = &mf;
- const TargetInstrInfo &TII = *TM.getInstrInfo();
- const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
- if (Fn.hasGC())
- GFI = &getAnalysis<GCModuleInfo>().getFunctionInfo(Fn);
- else
- GFI = 0;
- RegInfo = &MF->getRegInfo();
- DEBUG(errs() << "\n\n\n=== " << Fn.getName() << "\n");
- MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
- DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
- CurDAG->init(*MF, MMI, DW);
- FuncInfo->set(Fn, *MF, *CurDAG, EnableFastISel);
- SDL->init(GFI, *AA);
- for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
- if (InvokeInst *Invoke = dyn_cast<InvokeInst>(I->getTerminator()))
- // Mark landing pad.
- FuncInfo->MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
- SelectAllBasicBlocks(Fn, *MF, MMI, DW, TII);
- // If the first basic block in the function has live ins that need to be
- // copied into vregs, emit the copies into the top of the block before
- // emitting the code for the block.
- EmitLiveInCopies(MF->begin(), *RegInfo, TRI, TII);
- // Add function live-ins to entry block live-in set.
- for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(),
- E = RegInfo->livein_end(); I != E; ++I)
- MF->begin()->addLiveIn(I->first);
- #ifndef NDEBUG
- assert(FuncInfo->CatchInfoFound.size() == FuncInfo->CatchInfoLost.size() &&
- "Not all catch info was assigned to a landing pad!");
- #endif
- FuncInfo->clear();
- return true;
- }
- static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB,
- MachineModuleInfo *MMI, FunctionLoweringInfo &FLI) {
- for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I)
- if (EHSelectorInst *EHSel = dyn_cast<EHSelectorInst>(I)) {
- // Apply the catch info to DestBB.
- AddCatchInfo(*EHSel, MMI, FLI.MBBMap[DestBB]);
- #ifndef NDEBUG
- if (!FLI.MBBMap[SrcBB]->isLandingPad())
- FLI.CatchInfoFound.insert(EHSel);
- #endif
- }
- }
- void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
- BasicBlock::iterator Begin,
- BasicBlock::iterator End) {
- SDL->setCurrentBasicBlock(BB);
- // Lower all of the non-terminator instructions. If a call is emitted
- // as a tail call, cease emitting nodes for this block.
- for (BasicBlock::iterator I = Begin; I != End && !SDL->HasTailCall; ++I)
- if (!isa<TerminatorInst>(I))
- SDL->visit(*I);
- if (!SDL->HasTailCall) {
- // Ensure that all instructions which are used outside of their defining
- // blocks are available as virtual registers. Invoke is handled elsewhere.
- for (BasicBlock::iterator I = Begin; I != End; ++I)
- if (!isa<PHINode>(I) && !isa<InvokeInst>(I))
- SDL->CopyToExportRegsIfNeeded(I);
- // Handle PHI nodes in successor blocks.
- if (End == LLVMBB->end()) {
- HandlePHINodesInSuccessorBlocks(LLVMBB);
- // Lower the terminator after the copies are emitted.
- SDL->visit(*LLVMBB->getTerminator());
- }
- }
-
- // Make sure the root of the DAG is up-to-date.
- CurDAG->setRoot(SDL->getControlRoot());
- // Final step, emit the lowered DAG as machine code.
- CodeGenAndEmitDAG();
- SDL->clear();
- }
- void SelectionDAGISel::ComputeLiveOutVRegInfo() {
- SmallPtrSet<SDNode*, 128> VisitedNodes;
- SmallVector<SDNode*, 128> Worklist;
-
- Worklist.push_back(CurDAG->getRoot().getNode());
-
- APInt Mask;
- APInt KnownZero;
- APInt KnownOne;
-
- while (!Worklist.empty()) {
- SDNode *N = Worklist.back();
- Worklist.pop_back();
-
- // If we've already seen this node, ignore it.
- if (!VisitedNodes.insert(N))
- continue;
-
- // Otherwise, add all chain operands to the worklist.
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- if (N->getOperand(i).getValueType() == MVT::Other)
- Worklist.push_back(N->getOperand(i).getNode());
-
- // If this is a CopyToReg with a vreg dest, process it.
- if (N->getOpcode() != ISD::CopyToReg)
- continue;
-
- unsigned DestReg = cast<RegisterSDNode>(N->getOperand(1))->getReg();
- if (!TargetRegisterInfo::isVirtualRegister(DestReg))
- continue;
-
- // Ignore non-scalar or non-integer values.
- SDValue Src = N->getOperand(2);
- EVT SrcVT = Src.getValueType();
- if (!SrcVT.isInteger() || SrcVT.isVector())
- continue;
-
- unsigned NumSignBits = CurDAG->ComputeNumSignBits(Src);
- Mask = APInt::getAllOnesValue(SrcVT.getSizeInBits());
- CurDAG->ComputeMaskedBits(Src, Mask, KnownZero, KnownOne);
-
- // Only install this information if it tells us something.
- if (NumSignBits != 1 || KnownZero != 0 || KnownOne != 0) {
- DestReg -= TargetRegisterInfo::FirstVirtualRegister;
- if (DestReg >= FuncInfo->LiveOutRegInfo.size())
- FuncInfo->LiveOutRegInfo.resize(DestReg+1);
- FunctionLoweringInfo::LiveOutInfo &LOI =
- FuncInfo->LiveOutRegInfo[DestReg];
- LOI.NumSignBits = NumSignBits;
- LOI.KnownOne = KnownOne;
- LOI.KnownZero = KnownZero;
- }
- }
- }
- void SelectionDAGISel::CodeGenAndEmitDAG() {
- std::string GroupName;
- if (TimePassesIsEnabled)
- GroupName = "Instruction Selection and Scheduling";
- std::string BlockName;
- if (ViewDAGCombine1 || ViewLegalizeTypesDAGs || ViewLegalizeDAGs ||
- ViewDAGCombine2 || ViewDAGCombineLT || ViewISelDAGs || ViewSchedDAGs ||
- ViewSUnitDAGs)
- BlockName = MF->getFunction()->getNameStr() + ":" +
- BB->getBasicBlock()->getNameStr();
- DOUT << "Initial selection DAG:\n";
- DEBUG(CurDAG->dump());
- if (ViewDAGCombine1) CurDAG->viewGraph("dag-combine1 input for " + BlockName);
- // Run the DAG combiner in pre-legalize mode.
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("DAG Combining 1", GroupName);
- CurDAG->Combine(Unrestricted, *AA, OptLevel);
- } else {
- CurDAG->Combine(Unrestricted, *AA, OptLevel);
- }
-
- DOUT << "Optimized lowered selection DAG:\n";
- DEBUG(CurDAG->dump());
-
- // Second step, hack on the DAG until it only uses operations and types that
- // the target supports.
- if (!DisableLegalizeTypes) {
- if (ViewLegalizeTypesDAGs) CurDAG->viewGraph("legalize-types input for " +
- BlockName);
- bool Changed;
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("Type Legalization", GroupName);
- Changed = CurDAG->LegalizeTypes();
- } else {
- Changed = CurDAG->LegalizeTypes();
- }
- DOUT << "Type-legalized selection DAG:\n";
- DEBUG(CurDAG->dump());
- if (Changed) {
- if (ViewDAGCombineLT)
- CurDAG->viewGraph("dag-combine-lt input for " + BlockName);
- // Run the DAG combiner in post-type-legalize mode.
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("DAG Combining after legalize types", GroupName);
- CurDAG->Combine(NoIllegalTypes, *AA, OptLevel);
- } else {
- CurDAG->Combine(NoIllegalTypes, *AA, OptLevel);
- }
- DOUT << "Optimized type-legalized selection DAG:\n";
- DEBUG(CurDAG->dump());
- }
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("Vector Legalization", GroupName);
- Changed = CurDAG->LegalizeVectors();
- } else {
- Changed = CurDAG->LegalizeVectors();
- }
- if (Changed) {
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("Type Legalization 2", GroupName);
- Changed = CurDAG->LegalizeTypes();
- } else {
- Changed = CurDAG->LegalizeTypes();
- }
- if (ViewDAGCombineLT)
- CurDAG->viewGraph("dag-combine-lv input for " + BlockName);
- // Run the DAG combiner in post-type-legalize mode.
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("DAG Combining after legalize vectors", GroupName);
- CurDAG->Combine(NoIllegalOperations, *AA, OptLevel);
- } else {
- CurDAG->Combine(NoIllegalOperations, *AA, OptLevel);
- }
- DOUT << "Optimized vector-legalized selection DAG:\n";
- DEBUG(CurDAG->dump());
- }
- }
-
- if (ViewLegalizeDAGs) CurDAG->viewGraph("legalize input for " + BlockName);
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("DAG Legalization", GroupName);
- CurDAG->Legalize(DisableLegalizeTypes, OptLevel);
- } else {
- CurDAG->Legalize(DisableLegalizeTypes, OptLevel);
- }
-
- DOUT << "Legalized selection DAG:\n";
- DEBUG(CurDAG->dump());
-
- if (ViewDAGCombine2) CurDAG->viewGraph("dag-combine2 input for " + BlockName);
- // Run the DAG combiner in post-legalize mode.
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("DAG Combining 2", GroupName);
- CurDAG->Combine(NoIllegalOperations, *AA, OptLevel);
- } else {
- CurDAG->Combine(NoIllegalOperations, *AA, OptLevel);
- }
-
- DOUT << "Optimized legalized selection DAG:\n";
- DEBUG(CurDAG->dump());
- if (ViewISelDAGs) CurDAG->viewGraph("isel input for " + BlockName);
-
- if (OptLevel != CodeGenOpt::None)
- ComputeLiveOutVRegInfo();
- // Third, instruction select all of the operations to machine code, adding the
- // code to the MachineBasicBlock.
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("Instruction Selection", GroupName);
- InstructionSelect();
- } else {
- InstructionSelect();
- }
- DOUT << "Selected selection DAG:\n";
- DEBUG(CurDAG->dump());
- if (ViewSchedDAGs) CurDAG->viewGraph("scheduler input for " + BlockName);
- // Schedule machine code.
- ScheduleDAGSDNodes *Scheduler = CreateScheduler();
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("Instruction Scheduling", GroupName);
- Scheduler->Run(CurDAG, BB, BB->end());
- } else {
- Scheduler->Run(CurDAG, BB, BB->end());
- }
- if (ViewSUnitDAGs) Scheduler->viewGraph();
- // Emit machine code to BB. This can change 'BB' to the last block being
- // inserted into.
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("Instruction Creation", GroupName);
- BB = Scheduler->EmitSchedule();
- } else {
- BB = Scheduler->EmitSchedule();
- }
- // Free the scheduler state.
- if (TimePassesIsEnabled) {
- NamedRegionTimer T("Instruction Scheduling Cleanup", GroupName);
- delete Scheduler;
- } else {
- delete Scheduler;
- }
- DOUT << "Selected machine code:\n";
- DEBUG(BB->dump());
- }
- void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
- MachineFunction &MF,
- MachineModuleInfo *MMI,
- DwarfWriter *DW,
- const TargetInstrInfo &TII) {
- // Initialize the Fast-ISel state, if needed.
- FastISel *FastIS = 0;
- if (EnableFastISel)
- FastIS = TLI.createFastISel(MF, MMI, DW,
- FuncInfo->ValueMap,
- FuncInfo->MBBMap,
- FuncInfo->StaticAllocaMap
- #ifndef NDEBUG
- , FuncInfo->CatchInfoLost
- #endif
- );
- // Iterate over all basic blocks in the function.
- for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
- BasicBlock *LLVMBB = &*I;
- BB = FuncInfo->MBBMap[LLVMBB];
- BasicBlock::iterator const Begin = LLVMBB->begin();
- BasicBlock::iterator const End = LLVMBB->end();
- BasicBlock::iterator BI = Begin;
- // Lower any arguments needed in this block if this is the entry block.
- bool SuppressFastISel = false;
- if (LLVMBB == &Fn.getEntryBlock()) {
- LowerArguments(LLVMBB);
- // If any of the arguments has the byval attribute, forgo
- // fast-isel in the entry block.
- if (FastIS) {
- unsigned j = 1;
- for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end();
- I != E; ++I, ++j)
- if (Fn.paramHasAttr(j, Attribute::ByVal)) {
- if (EnableFastISelVerbose || EnableFastISelAbort)
- cerr << "FastISel skips entry block due to byval argument\n";
- SuppressFastISel = true;
- break;
- }
- }
- }
- if (MMI && BB->isLandingPad()) {
- // Add a label to mark the beginning of the landing pad. Deletion of the
- // landing pad can thus be detected via the MachineModuleInfo.
- unsigned LabelID = MMI->addLandingPad(BB);
- const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL);
- BuildMI(BB, SDL->getCurDebugLoc(), II).addImm(LabelID);
- // Mark exception register as live in.
- unsigned Reg = TLI.getExceptionAddressRegister();
- if (Reg) BB->addLiveIn(Reg);
- // Mark exception selector register as live in.
- Reg = TLI.getExceptionSelectorRegister();
- if (Reg) BB->addLiveIn(Reg);
- // FIXME: Hack around an exception handling flaw (PR1508): the personality
- // function and list of typeids logically belong to the invoke (or, if you
- // like, the basic block containing the invoke), and need to be associated
- // with it in the dwarf exception handling tables. Currently however the
- // information is provided by an intrinsic (eh.selector) that can be moved
- // to unexpected places by the optimizers: if the unwind edge is critical,
- // then breaking it can result in the intrinsics being in the successor of
- // the landing pad, not the landing pad itself. This results in exceptions
- // not being caught because no typeids are associated with the invoke.
- // This may not be the only way things can go wrong, but it is the only way
- // we try to work around for the moment.
- BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
- if (Br && Br->isUnconditional()) { // Critical edge?
- BasicBlock::iterator I, E;
- for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
- if (isa<EHSelectorInst>(I))
- break;
- if (I == E)
- // No catch info found - try to extract some from the successor.
- copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, *FuncInfo);
- }
- }
- // Before doing SelectionDAG ISel, see if FastISel has been requested.
- if (FastIS && !SuppressFastISel) {
- // Emit code for any incoming arguments. This must happen before
- // beginning FastISel on the entry block.
- if (LLVMBB == &Fn.getEntryBlock()) {
- CurDAG->setRoot(SDL->getControlRoot());
- CodeGenAndEmitDAG();
- SDL->clear();
- }
- FastIS->startNewBlock(BB);
- // Do FastISel on as many instructions as possible.
- for (; BI != End; ++BI) {
- // Just before the terminator instruction, insert instructions to
- // feed PHI nodes in successor blocks.
- if (isa<TerminatorInst>(BI))
- if (!HandlePHINodesInSuccessorBlocksFast(LLVMBB, FastIS)) {
- if (EnableFastISelVerbose || EnableFastISelAbort) {
- cerr << "FastISel miss: ";
- BI->dump();
- }
- assert(!EnableFastISelAbort &&
- "FastISel didn't handle a PHI in a successor");
- break;
- }
- // First try normal tablegen-generated "fast" selection.
- if (FastIS->SelectInstruction(BI))
- continue;
- // Next, try calling the target to attempt to handle the instruction.
- if (FastIS->TargetSelectInstruction(BI))
- continue;
- // Then handle certain instructions as single-LLVM-Instruction blocks.
- if (isa<CallInst>(BI)) {
- if (EnableFastISelVerbose || EnableFastISelAbort) {
- cerr << "FastISel missed call: ";
- BI->dump();
- }
- if (BI->getType() != Type::getVoidTy(*CurDAG->getContext())) {
- unsigned &R = FuncInfo->ValueMap[BI];
- if (!R)
- R = FuncInfo->CreateRegForValue(BI);
- }
- SDL->setCurDebugLoc(FastIS->getCurDebugLoc());
- SelectBasicBlock(LLVMBB, BI, next(BI));
- // If the instruction was codegen'd with multiple blocks,
- // inform the FastISel object where to resume inserting.
- FastIS->setCurrentBlock(BB);
- continue;
- }
- // Otherwise, give up on FastISel for the rest of the block.
- // For now, be a little lenient about non-branch terminators.
- if (!isa<TerminatorInst>(BI) || isa<BranchInst>(BI)) {
- if (EnableFastISelVerbose || EnableFastISelAbort) {
- cerr << "FastISel miss: ";
- BI->dump();
- }
- if (EnableFastISelAbort)
- // The "fast" selector couldn't handle something and bailed.
- // For the purpose of debugging, just abort.
- llvm_unreachable("FastISel didn't select the entire block");
- }
- break;
- }
- }
- // Run SelectionDAG instruction selection on the remainder of the block
- // not handled by FastISel. If FastISel is not run, this is the entire
- // block.
- if (BI != End) {
- // If FastISel is run and it has known DebugLoc then use it.
- if (FastIS && !FastIS->getCurDebugLoc().isUnknown())
- SDL->setCurDebugLoc(FastIS->getCurDebugLoc());
- SelectBasicBlock(LLVMBB, BI, End);
- }
- FinishBasicBlock();
- }
- delete FastIS;
- }
- void
- SelectionDAGISel::FinishBasicBlock() {
- DOUT << "Target-post-processed machine code:\n";
- DEBUG(BB->dump());
- DOUT << "Total amount of phi nodes to update: "
- << SDL->PHINodesToUpdate.size() << "\n";
- DEBUG(for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i)
- DOUT << "Node " << i << " : (" << SDL->PHINodesToUpdate[i].first
- << ", " << SDL->PHINodesToUpdate[i].second << ")\n";);
-
- // Next, now that we know what the last MBB the LLVM BB expanded is, update
- // PHI nodes in successors.
- if (SDL->SwitchCases.empty() &&
- SDL->JTCases.empty() &&
- SDL->BitTestCases.empty()) {
- for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i) {
- MachineInstr *PHI = SDL->PHINodesToUpdate[i].first;
- assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
- "This is not a machine PHI node that we are updating!");
- PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[i].second,
- false));
- PHI->addOperand(MachineOperand::CreateMBB(BB));
- }
- SDL->PHINodesToUpdate.clear();
- return;
- }
- for (unsigned i = 0, e = SDL->BitTestCases.size(); i != e; ++i) {
- // Lower header first, if it wasn't already lowered
- if (!SDL->BitTestCases[i].Emitted) {
- // Set the current basic block to the mbb we wish to insert the code into
- BB = SDL->BitTestCases[i].Parent;
- SDL->setCurrentBasicBlock(BB);
- // Emit the code
- SDL->visitBitTestHeader(SDL->BitTestCases[i]);
- CurDAG->setRoot(SDL->getRoot());
- CodeGenAndEmitDAG();
- SDL->clear();
- }
- for (unsigned j = 0, ej = SDL->BitTestCases[i].Cases.size(); j != ej; ++j) {
- // Set the current basic block to the mbb we wish to insert the code into
- BB = SDL->BitTestCases[i].Cases[j].ThisBB;
- SDL->setCurrentBasicBlock(BB);
- // Emit the code
- if (j+1 != ej)
- SDL->visitBitTestCase(SDL->BitTestCases[i].Cases[j+1].ThisBB,
- SDL->BitTestCases[i].Reg,
- SDL->BitTestCases[i].Cases[j]);
- else
- SDL->visitBitTestCase(SDL->BitTestCases[i].Default,
- SDL->BitTestCases[i].Reg,
- SDL->BitTestCases[i].Cases[j]);
-
-
- CurDAG->setRoot(SDL->getRoot());
- CodeGenAndEmitDAG();
- SDL->clear();
- }
- // Update PHI Nodes
- for (unsigned pi = 0, pe = SDL->PHINodesToUpdate.size(); pi != pe; ++pi) {
- MachineInstr *PHI = SDL->PHINodesToUpdate[pi].first;
- MachineBasicBlock *PHIBB = PHI->getParent();
- assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
- "This is not a machine PHI node that we are updating!");
- // This is "default" BB. We have two jumps to it. From "header" BB and
- // from last "case" BB.
- if (PHIBB == SDL->BitTestCases[i].Default) {
- PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
- false));
- PHI->addOperand(MachineOperand::CreateMBB(SDL->BitTestCases[i].Parent));
- PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
- false));
- PHI->addOperand(MachineOperand::CreateMBB(SDL->BitTestCases[i].Cases.
- back().ThisBB));
- }
- // One of "cases" BB.
- for (unsigned j = 0, ej = SDL->BitTestCases[i].Cases.size();
- j != ej; ++j) {
- MachineBasicBlock* cBB = SDL->BitTestCases[i].Cases[j].ThisBB;
- if (cBB->succ_end() !=
- std::find(cBB->succ_begin(),cBB->succ_end(), PHIBB)) {
- PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
- false));
- PHI->addOperand(MachineOperand::CreateMBB(cBB));
- }
- }
- }
- }
- SDL->BitTestCases.clear();
- // If the JumpTable record is filled in, then we need to emit a jump table.
- // Updating the PHI nodes is tricky in this case, since we need to determine
- // whether the PHI is a successor of the range check MBB or the jump table MBB
- for (unsigned i = 0, e = SDL->JTCases.size(); i != e; ++i) {
- // Lower header first, if it wasn't already lowered
- if (!SDL->JTCases[i].first.Emitted) {
- // Set the current basic block to the mbb we wish to insert the code into
- BB = SDL->JTCases[i].first.HeaderBB;
- SDL->setCurrentBasicBlock(BB);
- // Emit the code
- SDL->visitJumpTableHeader(SDL->JTCases[i].second, SDL->JTCases[i].first);
- CurDAG->setRoot(SDL->getRoot());
- CodeGenAndEmitDAG();
- SDL->clear();
- }
-
- // Set the current basic block to the mbb we wish to insert the code into
- BB = SDL->JTCases[i].second.MBB;
- SDL->setCurrentBasicBlock(BB);
- // Emit the code
- SDL->visitJumpTable(SDL->JTCases[i].second);
- CurDAG->setRoot(SDL->getRoot());
- CodeGenAndEmitDAG();
- SDL->clear();
-
- // Update PHI Nodes
- for (unsigned pi = 0, pe = SDL->PHINodesToUpdate.size(); pi != pe; ++pi) {
- MachineInstr *PHI = SDL->PHINodesToUpdate[pi].first;
- MachineBasicBlock *PHIBB = PHI->getParent();
- assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
- "This is not a machine PHI node that we are updating!");
- // "default" BB. We can go there only from header BB.
- if (PHIBB == SDL->JTCases[i].second.Default) {
- PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
- false));
- PHI->addOperand(MachineOperand::CreateMBB(SDL->JTCases[i].first.HeaderBB));
- }
- // JT BB. Just iterate over successors here
- if (BB->succ_end() != std::find(BB->succ_begin(),BB->succ_end(), PHIBB)) {
- PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second,
- false));
- PHI->addOperand(MachineOperand::CreateMBB(BB));
- }
- }
- }
- SDL->JTCases.clear();
-
- // If the switch block involved a branch to one of the actual successors, we
- // need to update PHI nodes in that block.
- for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i) {
- MachineInstr *PHI = SDL->PHINodesToUpdate[i].first;
- assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
- "This is not a machine PHI node that we are updating!");
- if (BB->isSuccessor(PHI->getParent())) {
- PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[i].second,
- false));
- PHI->addOperand(MachineOperand::CreateMBB(BB));
- }
- }
-
- // If we generated any switch lowering information, build and codegen any
- // additional DAGs necessary.
- for (unsigned i = 0, e = SDL->SwitchCases.size(); i != e; ++i) {
- // Set the current basic block to the mbb we wish to insert the code into
- BB = SDL->SwitchCases[i].ThisBB;
- SDL->setCurrentBasicBlock(BB);
-
- // Emit the code
- SDL->visitSwitchCase(SDL->SwitchCases[i]);
- CurDAG->setRoot(SDL->getRoot());
- CodeGenAndEmitDAG();
- SDL->clear();
-
- // Handle any PHI nodes in successors of this chunk, as if we were coming
- // from the original BB before switch expansion. Note that PHI nodes can
- // occur multiple times in PHINodesToUpdate. We have to be very careful to
- // handle them the right number of times.
- while ((BB = SDL->SwitchCases[i].TrueBB)) { // Handle LHS and RHS.
- for (MachineBasicBlock::iterator Phi = BB->begin();
- Phi != BB->end() && Phi->getOpcode() == TargetInstrInfo::PHI; ++Phi){
- // This value for this PHI node is recorded in PHINodesToUpdate, get it.
- for (unsigned pn = 0; ; ++pn) {
- assert(pn != SDL->PHINodesToUpdate.size() &&
- "Didn't find PHI entry!");
- if (SDL->PHINodesToUpdate[pn].first == Phi) {
- Phi->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pn].
- second, false));
- Phi->addOperand(MachineOperand::CreateMBB(SDL->SwitchCases[i].ThisBB));
- break;
- }
- }
- }
-
- // Don't process RHS if same block as LHS.
- if (BB == SDL->SwitchCases[i].FalseBB)
- SDL->SwitchCases[i].FalseBB = 0;
-
- // If we haven't handled the RHS, do so now. Otherwise, we're done.
- SDL->SwitchCases[i].TrueBB = SDL->SwitchCases[i].FalseBB;
- SDL->SwitchCases[i].FalseBB = 0;
- }
- assert(SDL->SwitchCases[i].TrueBB == 0 && SDL->SwitchCases[i].FalseBB == 0);
- }
- SDL->SwitchCases.clear();
- SDL->PHINodesToUpdate.clear();
- }
- /// Create the scheduler. If a specific scheduler was specified
- /// via the SchedulerRegistry, use it, otherwise select the
- /// one preferred by the target.
- ///
- ScheduleDAGSDNodes *SelectionDAGISel::CreateScheduler() {
- RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault();
-
- if (!Ctor) {
- Ctor = ISHeuristic;
- RegisterScheduler::setDefault(Ctor);
- }
-
- return Ctor(this, OptLevel);
- }
- ScheduleHazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
- return new ScheduleHazardRecognizer();
- }
- //===----------------------------------------------------------------------===//
- // Helper functions used by the generated instruction selector.
- //===----------------------------------------------------------------------===//
- // Calls to these methods are generated by tblgen.
- /// CheckAndMask - The isel is trying to match something like (and X, 255). If
- /// the dag combiner simplified the 255, we still want to match. RHS is the
- /// actual value in the DAG on the RHS of an AND, and DesiredMaskS is the value
- /// specified in the .td file (e.g. 255).
- bool SelectionDAGISel::CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
- int64_t DesiredMaskS) const {
- const APInt &ActualMask = RHS->getAPIntValue();
- const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
-
- // If the actual mask exactly matches, success!
- if (ActualMask == DesiredMask)
- return true;
-
- // If the actual AND mask is allowing unallowed bits, this doesn't match.
- if (ActualMask.intersects(~DesiredMask))
- return false;
-
- // Otherwise, the DAG Combiner may have proven that the value coming in is
- // either already zero or is not demanded. Check for known zero input bits.
- APInt NeededMask = DesiredMask & ~ActualMask;
- if (CurDAG->MaskedValueIsZero(LHS, NeededMask))
- return true;
-
- // TODO: check to see if missing bits are just not demanded.
- // Otherwise, this pattern doesn't match.
- return false;
- }
- /// CheckOrMask - The isel is trying to match something like (or X, 255). If
- /// the dag combiner simplified the 255, we still want to match. RHS is the
- /// actual value in the DAG on the RHS of an OR, and DesiredMaskS is the value
- /// specified in the .td file (e.g. 255).
- bool SelectionDAGISel::CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
- int64_t DesiredMaskS) const {
- const APInt &ActualMask = RHS->getAPIntValue();
- const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS);
-
- // If the actual mask exactly matches, success!
- if (ActualMask == DesiredMask)
- return true;
-
- // If the actual AND mask is allowing unallowed bits, this doesn't match.
- if (ActualMask.intersects(~DesiredMask))
- return false;
-
- // Otherwise, the DAG Combiner may have proven that the value coming in is
- // either already zero or is not demanded. Check for known zero input bits.
- APInt NeededMask = DesiredMask & ~ActualMask;
-
- APInt KnownZero, KnownOne;
- CurDAG->ComputeMaskedBits(LHS, NeededMask, KnownZero, KnownOne);
-
- // If all the missing bits in the or are already known to be set, match!
- if ((NeededMask & KnownOne) == NeededMask)
- return true;
-
- // TODO: check to see if missing bits are just not demanded.
-
- // Otherwise, this pattern doesn't match.
- return false;
- }
- /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
- /// by tblgen. Others should not call it.
- void SelectionDAGISel::
- SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops) {
- std::vector<SDValue> InOps;
- std::swap(InOps, Ops);
- Ops.push_back(InOps[0]); // input chain.
- Ops.push_back(InOps[1]); // input asm string.
- unsigned i = 2, e = InOps.size();
- if (InOps[e-1].getValueType() == MVT::Flag)
- --e; // Don't process a flag operand if it is here.
-
- while (i != e) {
- unsigned Flags = cast<ConstantSDNode>(InOps[i])->getZExtValue();
- if ((Flags & 7) != 4 /*MEM*/) {
- // Just skip over this operand, copying the operands verbatim.
- Ops.insert(Ops.end(), InOps.begin()+i,
- InOps.begin()+i+InlineAsm::getNumOperandRegisters(Flags) + 1);
- i += InlineAsm::getNumOperandRegisters(Flags) + 1;
- } else {
- assert(InlineAsm::getNumOperandRegisters(Flags) == 1 &&
- "Memory operand with multiple values?");
- // Otherwise, this is a memory operand. Ask the target to select it.
- std::vector<SDValue> SelOps;
- if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) {
- llvm_report_error("Could not match memory address. Inline asm"
- " failure!");
- }
-
- // Add this to the output node.
- EVT IntPtrTy = TLI.getPointerTy();
- Ops.push_back(CurDAG->getTargetConstant(4/*MEM*/ | (SelOps.size()<< 3),
- IntPtrTy));
- Ops.insert(Ops.end(), SelOps.begin(), SelOps.end());
- i += 2;
- }
- }
-
- // Add the flag input back if present.
- if (e != InOps.size())
- Ops.push_back(InOps.back());
- }
- /// findFlagUse - Return use of EVT::Flag value produced by the specified
- /// SDNode.
- ///
- static SDNode *findFlagUse(SDNode *N) {
- unsigned FlagResNo = N->getNumValues()-1;
- for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
- SDUse &Use = I.getUse();
- if (Use.getResNo() == FlagResNo)
- return Use.getUser();
- }
- return NULL;
- }
- /// findNonImmUse - Return true if "Use" is a non-immediate use of "Def".
- /// This function recursively traverses up the operand chain, ignoring
- /// certain nodes.
- static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
- SDNode *Root,
- SmallPtrSet<SDNode*, 16> &Visited) {
- if (Use->getNodeId() < Def->getNodeId() ||
- !Visited.insert(Use))
- return false;
- for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) {
- SDNode *N = Use->getOperand(i).getNode();
- if (N == Def) {
- if (Use == ImmedUse || Use == Root)
- continue; // We are not looking for immediate use.
- assert(N != Root);
- return true;
- }
- // Traverse up the operand chain.
- if (findNonImmUse(N, Def, ImmedUse, Root, Visited))
- return true;
- }
- return false;
- }
- /// isNonImmUse - Start searching from Root up the DAG to check is Def can
- /// be reached. Return true if that's the case. However, ignore direct uses
- /// by ImmedUse (which would be U in the example illustrated in
- /// IsLegalAndProfitableToFold) and by Root (which can happen in the store
- /// case).
- /// FIXME: to be really generic, we should allow direct use by any node
- /// that is being folded. But realisticly since we only fold loads which
- /// have one non-chain use, we only need to watch out for load/op/store
- /// and load/op/cmp case where the root (store / cmp) may reach the load via
- /// its chain operand.
- static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) {
- SmallPtrSet<SDNode*, 16> Visited;
- return findNonImmUse(Root, Def, ImmedUse, Root, Visited);
- }
- /// IsLegalAndProfitableToFold - Returns true if the specific operand node N of
- /// U can be folded during instruction selection that starts at Root and
- /// folding N is profitable.
- bool SelectionDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
- SDNode *Root) const {
- if (OptLevel == CodeGenOpt::None) return false;
- // If Root use can somehow reach N through a path that that doesn't contain
- // U then folding N would create a cycle. e.g. In the following
- // diagram, Root can reach N through X. If N is folded into into Root, then
- // X is both a predecessor and a successor of U.
- //
- // [N*] //
- // ^ ^ //
- // / \ //
- // [U*] [X]? //
- // ^ ^ //
- // \ / //
- // \ / //
- // [Root*] //
- //
- // * indicates nodes to be folded together.
- //
- // If Root produces a flag, then it gets (even more) interesting. Since it
- // will be "glued" together with its flag use in the scheduler, we need to
- // check if it might reach N.
- //
- // [N*] //
- // ^ ^ //
- // / \ //
- // [U*] [X]? //
- // ^ ^ //
- // \ \ //
- // \ | //
- // [Root*] | //
- // ^ | //
- // f | //
- // | / //
- // [Y] / //
- // ^ / //
- // f / //
- // | / //
- // [FU] //
- //
- // If FU (flag use) indirectly reaches N (the load), and Root folds N
- // (call it Fold), then X is a predecessor of FU and a successor of
- // Fold. But since Fold and FU are flagged together, this will create
- // a cycle in the scheduling graph.
- EVT VT = Root->getValueType(Root->getNumValues()-1);
- while (VT == MVT::Flag) {
- SDNode *FU = findFlagUse(Root);
- if (FU == NULL)
- break;
- Root = FU;
- VT = Root->getValueType(Root->getNumValues()-1);
- }
- return !isNonImmUse(Root, N, U);
- }
- char SelectionDAGISel::ID = 0;
|