X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAGISel.cpp;h=1676e2dfe08fb477b6cb01df9bec642449a880d7;hb=5666fc71f0e2ed2c0400d8bca079a1dd3f33fe53;hp=f6c5d90f47ae1386c1c1f91370298d903b773220;hpb=1114aa2fc68b45b7cc2100585081ebeba0f3f694;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index f6c5d90f47a..1676e2dfe08 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -467,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(), @@ -598,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. @@ -607,6 +645,47 @@ 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)) { + Succ1Succ = *Succ1->succ_begin(); + } + if ((Succ2->size() == 1 && Succ2->begin()->isUnconditionalBranch()) || + (Succ2->size() == 0)) { + Succ2Succ = *Succ2->succ_begin(); + } + + bool HasCommonDest = Succ1Succ && Succ1Succ == Succ2Succ; + if (HasCommonDest) { + auto MBBIter = MBB.end(); + std::advance(MBBIter, -2); + assert(MBBIter->isConditionalBranch()); + MBBIter->disableCanEliminateMachineInstr(); + 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()));