diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 90 |
1 files changed, 39 insertions, 51 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 6c57c72d47a7..1f0432196a2d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -215,6 +215,7 @@ namespace llvm { OptLevelChanger(SelectionDAGISel &ISel, CodeGenOpt::Level NewOptLevel) : IS(ISel) { SavedOptLevel = IS.OptLevel; + SavedFastISel = IS.TM.Options.EnableFastISel; if (NewOptLevel == SavedOptLevel) return; IS.OptLevel = NewOptLevel; @@ -223,7 +224,6 @@ namespace llvm { << IS.MF->getFunction().getName() << "\n"); LLVM_DEBUG(dbgs() << "\tBefore: -O" << SavedOptLevel << " ; After: -O" << NewOptLevel << "\n"); - SavedFastISel = IS.TM.Options.EnableFastISel; if (NewOptLevel == CodeGenOpt::None) { IS.TM.setFastISel(IS.TM.getO0WantsFastISel()); LLVM_DEBUG( @@ -337,7 +337,8 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { if (UseMBPI && OptLevel != CodeGenOpt::None) AU.addRequired<BranchProbabilityInfoWrapperPass>(); AU.addRequired<ProfileSummaryInfoWrapperPass>(); - LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU); + if (OptLevel != CodeGenOpt::None) + LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU); MachineFunctionPass::getAnalysisUsage(AU); } @@ -441,9 +442,9 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>(); LoopInfo *LI = LIWP ? &LIWP->getLoopInfo() : nullptr; auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); - auto *BFI = (PSI && PSI->hasProfileSummary()) ? - &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI() : - nullptr; + BlockFrequencyInfo *BFI = nullptr; + if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOpt::None) + BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI(); LLVM_DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n"); @@ -513,15 +514,15 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // registers. If we don't apply the reg fixups before, some registers may // appear as unused and will be skipped, resulting in bad MI. MachineRegisterInfo &MRI = MF->getRegInfo(); - for (DenseMap<unsigned, unsigned>::iterator I = FuncInfo->RegFixups.begin(), + for (DenseMap<Register, Register>::iterator I = FuncInfo->RegFixups.begin(), E = FuncInfo->RegFixups.end(); I != E; ++I) { - unsigned From = I->first; - unsigned To = I->second; + Register From = I->first; + Register To = I->second; // If To is also scheduled to be replaced, find what its ultimate // replacement is. while (true) { - DenseMap<unsigned, unsigned>::iterator J = FuncInfo->RegFixups.find(To); + DenseMap<Register, Register>::iterator J = FuncInfo->RegFixups.find(To); if (J == E) break; To = J->second; @@ -622,7 +623,9 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // Otherwise this is another use or second copy use. CopyUseMI = nullptr; break; } - if (CopyUseMI) { + if (CopyUseMI && + TRI.getRegSizeInBits(LDI->second, MRI) == + TRI.getRegSizeInBits(CopyUseMI->getOperand(0).getReg(), MRI)) { // Use MI's debug location, which describes where Variable was // declared, rather than whatever is attached to CopyUseMI. MachineInstr *NewMI = @@ -658,36 +661,6 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // Determine if floating point is used for msvc computeUsesMSVCFloatingPoint(TM.getTargetTriple(), Fn, MF->getMMI()); - // Replace forward-declared registers with the registers containing - // the desired value. - for (DenseMap<unsigned, unsigned>::iterator - I = FuncInfo->RegFixups.begin(), E = FuncInfo->RegFixups.end(); - I != E; ++I) { - unsigned From = I->first; - unsigned To = I->second; - // If To is also scheduled to be replaced, find what its ultimate - // replacement is. - while (true) { - DenseMap<unsigned, unsigned>::iterator J = FuncInfo->RegFixups.find(To); - if (J == E) break; - To = J->second; - } - // Make sure the new register has a sufficiently constrained register class. - if (Register::isVirtualRegister(From) && Register::isVirtualRegister(To)) - MRI.constrainRegClass(To, MRI.getRegClass(From)); - // Replace it. - - - // Replacing one register with another won't touch the kill flags. - // We need to conservatively clear the kill flags as a kill on the old - // register might dominate existing uses of the new register. - if (!MRI.use_empty(To)) - MRI.clearKillFlags(From); - MRI.replaceRegWith(From, To); - } - - TLI->finalizeLowering(*MF); - // Release function-specific state. SDB and CurDAG are already cleared // at this point. FuncInfo->clear(); @@ -1321,8 +1294,11 @@ static void processDbgDeclares(FunctionLoweringInfo &FuncInfo) { assert(DI->getVariable() && "Missing variable"); assert(DI->getDebugLoc() && "Missing location"); const Value *Address = DI->getAddress(); - if (!Address) + if (!Address) { + LLVM_DEBUG(dbgs() << "processDbgDeclares skipping " << *DI + << " (bad address)\n"); continue; + } // Look through casts and constant offset GEPs. These mostly come from // inalloca. @@ -1347,6 +1323,8 @@ static void processDbgDeclares(FunctionLoweringInfo &FuncInfo) { if (Offset.getBoolValue()) Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset, Offset.getZExtValue()); + LLVM_DEBUG(dbgs() << "processDbgDeclares: setVariableDbgInfo FI=" << FI + << ", " << *DI << "\n"); MF->setVariableDbgInfo(DI->getVariable(), Expr, FI, DI->getDebugLoc()); } } @@ -1513,8 +1491,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { // to keep track of gc-relocates for a particular gc-statepoint. This is // done by SelectionDAGBuilder::LowerAsSTATEPOINT, called before // visitGCRelocate. - if (isa<CallInst>(Inst) && !isStatepoint(Inst) && !isGCRelocate(Inst) && - !isGCResult(Inst)) { + if (isa<CallInst>(Inst) && !isa<GCStatepointInst>(Inst) && + !isa<GCRelocateInst>(Inst) && !isa<GCResultInst>(Inst)) { OptimizationRemarkMissed R("sdagisel", "FastISelFailure", Inst->getDebugLoc(), LLVMBB); @@ -1532,7 +1510,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { if (!Inst->getType()->isVoidTy() && !Inst->getType()->isTokenTy() && !Inst->use_empty()) { - unsigned &R = FuncInfo->ValueMap[Inst]; + Register &R = FuncInfo->ValueMap[Inst]; if (!R) R = FuncInfo->CreateRegs(Inst); } @@ -2234,14 +2212,14 @@ bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root, return !findNonImmUse(Root, N.getNode(), U, IgnoreChains); } -void SelectionDAGISel::Select_INLINEASM(SDNode *N, bool Branch) { +void SelectionDAGISel::Select_INLINEASM(SDNode *N) { SDLoc DL(N); std::vector<SDValue> Ops(N->op_begin(), N->op_end()); SelectInlineAsmMemoryOperands(Ops, DL); const EVT VTs[] = {MVT::Other, MVT::Glue}; - SDValue New = CurDAG->getNode(Branch ? ISD::INLINEASM_BR : ISD::INLINEASM, DL, VTs, Ops); + SDValue New = CurDAG->getNode(N->getOpcode(), DL, VTs, Ops); New->setNodeId(-1); ReplaceUses(N, New.getNode()); CurDAG->RemoveDeadNode(N); @@ -2285,6 +2263,14 @@ void SelectionDAGISel::Select_UNDEF(SDNode *N) { CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, N->getValueType(0)); } +void SelectionDAGISel::Select_FREEZE(SDNode *N) { + // TODO: We don't have FREEZE pseudo-instruction in MachineInstr-level now. + // If FREEZE instruction is added later, the code below must be changed as + // well. + CurDAG->SelectNodeTo(N, TargetOpcode::COPY, N->getValueType(0), + N->getOperand(0)); +} + /// GetVBR - decode a vbr encoding whose top bit is set. LLVM_ATTRIBUTE_ALWAYS_INLINE static inline uint64_t GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) { @@ -2804,13 +2790,13 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, return; case ISD::AssertSext: case ISD::AssertZext: + case ISD::AssertAlign: ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0)); CurDAG->RemoveDeadNode(NodeToMatch); return; case ISD::INLINEASM: case ISD::INLINEASM_BR: - Select_INLINEASM(NodeToMatch, - NodeToMatch->getOpcode() == ISD::INLINEASM_BR); + Select_INLINEASM(NodeToMatch); return; case ISD::READ_REGISTER: Select_READ_REGISTER(NodeToMatch); @@ -2821,6 +2807,9 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, case ISD::UNDEF: Select_UNDEF(NodeToMatch); return; + case ISD::FREEZE: + Select_FREEZE(NodeToMatch); + return; } assert(!NodeToMatch->isMachineOpcode() && "Node already selected!"); @@ -3693,12 +3682,11 @@ bool SelectionDAGISel::isOrEquivalentToAdd(const SDNode *N) const { // Detect when "or" is used to add an offset to a stack object. if (auto *FN = dyn_cast<FrameIndexSDNode>(N->getOperand(0))) { MachineFrameInfo &MFI = MF->getFrameInfo(); - unsigned A = MFI.getObjectAlignment(FN->getIndex()); - assert(isPowerOf2_32(A) && "Unexpected alignment"); + Align A = MFI.getObjectAlign(FN->getIndex()); int32_t Off = C->getSExtValue(); // If the alleged offset fits in the zero bits guaranteed by // the alignment, then this or is really an add. - return (Off >= 0) && (((A - 1) & Off) == unsigned(Off)); + return (Off >= 0) && (((A.value() - 1) & Off) == unsigned(Off)); } return false; } |