X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAGISel.cpp;h=491d7ec451c0525740732541e9e0b2b0625c063a;hp=04895e7702fc92d9a97a0891450f667983f7c44f;hb=20a42bb20d43b80e322c95dd99b64a5a4566fe08;hpb=de9bf0f80e8262b0eae2e826a35dde0a346391e4 diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 04895e7702f..491d7ec451c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -19,7 +19,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/CFG.h" -#include "llvm/Analysis/LibCallSemantics.h" +#include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/FastISel.h" @@ -264,13 +264,17 @@ namespace llvm { return; IS.OptLevel = NewOptLevel; IS.TM.setOptLevel(NewOptLevel); - SavedFastISel = IS.TM.Options.EnableFastISel; - if (NewOptLevel == CodeGenOpt::None) - IS.TM.setFastISel(true); DEBUG(dbgs() << "\nChanging optimization level for Function " << IS.MF->getFunction()->getName() << "\n"); DEBUG(dbgs() << "\tBefore: -O" << SavedOptLevel << " ; After: -O" << NewOptLevel << "\n"); + SavedFastISel = IS.TM.Options.EnableFastISel; + if (NewOptLevel == CodeGenOpt::None) { + IS.TM.setFastISel(IS.TM.getO0WantsFastISel()); + DEBUG(dbgs() << "\tFastISel is " + << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled") + << "\n"); + } } ~OptLevelChanger() { @@ -463,15 +467,50 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { MF->setHasInlineAsm(false); + FuncInfo->SplitCSR = false; + SmallVector Returns; + + // We split CSR if the target supports it for the given function + // and the function has only return exits. + if (TLI->supportSplitCSR(MF)) { + FuncInfo->SplitCSR = true; + + // Collect all the return blocks. + for (const BasicBlock &BB : Fn) { + if (!succ_empty(&BB)) + continue; + + const TerminatorInst *Term = BB.getTerminator(); + if (isa(Term)) + continue; + if (isa(Term)) { + Returns.push_back(FuncInfo->MBBMap[&BB]); + continue; + } + + // Bail out if the exit block is not Return nor Unreachable. + FuncInfo->SplitCSR = false; + break; + } + } + + MachineBasicBlock *EntryMBB = &MF->front(); + if (FuncInfo->SplitCSR) + // This performs initialization so lowering for SplitCSR will be correct. + TLI->initializeSplitCSR(EntryMBB); + SelectAllBasicBlocks(Fn); // 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. - MachineBasicBlock *EntryMBB = &MF->front(); const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo(); RegInfo->EmitLiveInCopies(EntryMBB, TRI, *TII); + // Insert copies in the entry block and the return blocks. + if (FuncInfo->SplitCSR) + TLI->insertCopiesSplitCSR(EntryMBB, Returns); + DenseMap LiveInMap; if (!FuncInfo->ArgDbgValues.empty()) for (MachineRegisterInfo::livein_iterator LI = RegInfo->livein_begin(), @@ -594,6 +633,9 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { MRI.replaceRegWith(From, To); } + if (TLI->hasCopyImplyingStackAdjustment(MF)) + MFI->setHasCopyImplyingStackAdjustment(true); + // Freeze the set of reserved registers now that MachineFrameInfo has been // set up. All the information required by getReservedRegs() should be // available now. @@ -603,6 +645,50 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // at this point. FuncInfo->clear(); + // XXX-update: Right after instruction selection, check through the + // intentionally added fake conditional branches and mark them as unremovable. + for (auto& MBB : *MF) { + // Check whether MBB has two successors which only contains an unconditional + // branch to the same destination. + if (MBB.succ_size() != 2 || + !MBB.getLastNonDebugInstr()->isUnconditionalBranch()) { + continue; + } + auto MBBSuccIter = MBB.succ_begin(); + auto* Succ1 = *MBBSuccIter; + MBBSuccIter++; + auto* Succ2 = *MBBSuccIter; + + MachineBasicBlock* Succ1Succ = nullptr; + MachineBasicBlock* Succ2Succ = nullptr; + if ((Succ1->size() == 1 && Succ1->begin()->isUnconditionalBranch()) || + (Succ1->size() == 0)) { + if (Succ1->succ_size()) { + Succ1Succ = *Succ1->succ_begin(); + } + } + if ((Succ2->size() == 1 && Succ2->begin()->isUnconditionalBranch()) || + (Succ2->size() == 0)) { + if (Succ1->succ_size()) { + Succ2Succ = *Succ2->succ_begin(); + } + } + + bool HasCommonDest = Succ1Succ && Succ1Succ == Succ2Succ; + if (HasCommonDest) { + auto MBBIter = MBB.end(); + std::advance(MBBIter, -2); + assert(MBBIter->isConditionalBranch()); + MBB.disableCanEliminateMachineBB(); + Succ1->disableCanEliminateMachineBB(); + Succ2->disableCanEliminateMachineBB(); + Succ1Succ->disableCanEliminateMachineBB(); + DEBUG(dbgs() << "Mark as unremovable machine basic block: " << MBB + << "\nMark as unremovable branch instruction: " << *MBBIter + << "\n"); + } + } + DEBUG(dbgs() << "*** MachineFunction at end of ISel ***\n"); DEBUG(MF->print(dbgs())); @@ -1486,10 +1572,9 @@ SelectionDAGISel::FinishBasicBlock() { CodeGenAndEmitDAG(); } - uint32_t UnhandledWeight = SDB->BitTestCases[i].Weight; - + BranchProbability UnhandledProb = SDB->BitTestCases[i].Prob; for (unsigned j = 0, ej = SDB->BitTestCases[i].Cases.size(); j != ej; ++j) { - UnhandledWeight -= SDB->BitTestCases[i].Cases[j].ExtraWeight; + UnhandledProb -= SDB->BitTestCases[i].Cases[j].ExtraProb; // Set the current basic block to the mbb we wish to insert the code into FuncInfo->MBB = SDB->BitTestCases[i].Cases[j].ThisBB; FuncInfo->InsertPt = FuncInfo->MBB->end(); @@ -1509,7 +1594,7 @@ SelectionDAGISel::FinishBasicBlock() { SDB->visitBitTestCase(SDB->BitTestCases[i], NextMBB, - UnhandledWeight, + UnhandledProb, SDB->BitTestCases[i].Reg, SDB->BitTestCases[i].Cases[j], FuncInfo->MBB);