diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 85 |
1 files changed, 75 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 7bae5048fc0e..1415cce3b1df 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -270,6 +270,10 @@ namespace llvm { return createHybridListDAGScheduler(IS, OptLevel); if (TLI->getSchedulingPreference() == Sched::VLIW) return createVLIWDAGScheduler(IS, OptLevel); + if (TLI->getSchedulingPreference() == Sched::Fast) + return createFastDAGScheduler(IS, OptLevel); + if (TLI->getSchedulingPreference() == Sched::Linearize) + return createDAGLinearizer(IS, OptLevel); assert(TLI->getSchedulingPreference() == Sched::ILP && "Unknown sched type!"); return createILPListDAGScheduler(IS, OptLevel); @@ -571,8 +575,11 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { LiveInMap.insert(LI); // Insert DBG_VALUE instructions for function arguments to the entry block. + bool InstrRef = TM.Options.ValueTrackingVariableLocations; for (unsigned i = 0, e = FuncInfo->ArgDbgValues.size(); i != e; ++i) { - MachineInstr *MI = FuncInfo->ArgDbgValues[e-i-1]; + MachineInstr *MI = FuncInfo->ArgDbgValues[e - i - 1]; + assert(MI->getOpcode() != TargetOpcode::DBG_VALUE_LIST && + "Function parameters should not be described by DBG_VALUE_LIST."); bool hasFI = MI->getOperand(0).isFI(); Register Reg = hasFI ? TRI.getFrameRegister(*MF) : MI->getOperand(0).getReg(); @@ -589,6 +596,10 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { << Register::virtReg2Index(Reg) << "\n"); } + // Don't try and extend through copies in instruction referencing mode. + if (InstrRef) + continue; + // If Reg is live-in then update debug info to track its copy in a vreg. DenseMap<unsigned, unsigned>::iterator LDI = LiveInMap.find(Reg); if (LDI != LiveInMap.end()) { @@ -605,6 +616,8 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { "DBG_VALUE with nonzero offset"); assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); + assert(MI->getOpcode() != TargetOpcode::DBG_VALUE_LIST && + "Didn't expect to see a DBG_VALUE_LIST here"); // Def is never a terminator here, so it is ok to increment InsertPos. BuildMI(*EntryMBB, ++InsertPos, DL, TII->get(TargetOpcode::DBG_VALUE), IsIndirect, LDI->second, Variable, Expr); @@ -638,6 +651,10 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { } } + // For debug-info, in instruction referencing mode, we need to perform some + // post-isel maintenence. + MF->finalizeDebugInstrRefs(); + // Determine if there are any calls in this machine function. MachineFrameInfo &MFI = MF->getFrameInfo(); for (const auto &MBB : *MF) { @@ -1419,9 +1436,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) { for (const BasicBlock *LLVMBB : RPOT) { if (OptLevel != CodeGenOpt::None) { bool AllPredsVisited = true; - for (const_pred_iterator PI = pred_begin(LLVMBB), PE = pred_end(LLVMBB); - PI != PE; ++PI) { - if (!FuncInfo->VisitedBBs.count(*PI)) { + for (const BasicBlock *Pred : predecessors(LLVMBB)) { + if (!FuncInfo->VisitedBBs.count(Pred)) { AllPredsVisited = false; break; } @@ -1691,9 +1707,9 @@ static bool MIIsInTerminatorSequence(const MachineInstr &MI) { /// terminator, but additionally the copies that move the vregs into the /// physical registers. static MachineBasicBlock::iterator -FindSplitPointForStackProtector(MachineBasicBlock *BB) { +FindSplitPointForStackProtector(MachineBasicBlock *BB, + const TargetInstrInfo &TII) { MachineBasicBlock::iterator SplitPoint = BB->getFirstTerminator(); - // if (SplitPoint == BB->begin()) return SplitPoint; @@ -1701,6 +1717,31 @@ FindSplitPointForStackProtector(MachineBasicBlock *BB) { MachineBasicBlock::iterator Previous = SplitPoint; --Previous; + if (TII.isTailCall(*SplitPoint) && + Previous->getOpcode() == TII.getCallFrameDestroyOpcode()) { + // call itself, then we must insert before the sequence even starts. For + // example: + // <split point> + // ADJCALLSTACKDOWN ... + // <Moves> + // ADJCALLSTACKUP ... + // TAILJMP somewhere + // On the other hand, it could be an unrelated call in which case this tail call + // has to register moves of its own and should be the split point. For example: + // ADJCALLSTACKDOWN + // CALL something_else + // ADJCALLSTACKUP + // <split point> + // TAILJMP somewhere + do { + --Previous; + if (Previous->isCall()) + return SplitPoint; + } while(Previous->getOpcode() != TII.getCallFrameSetupOpcode()); + + return Previous; + } + while (MIIsInTerminatorSequence(*Previous)) { SplitPoint = Previous; if (Previous == Start) @@ -1740,7 +1781,7 @@ SelectionDAGISel::FinishBasicBlock() { // Add load and check to the basicblock. FuncInfo->MBB = ParentMBB; FuncInfo->InsertPt = - FindSplitPointForStackProtector(ParentMBB); + FindSplitPointForStackProtector(ParentMBB, *TII); SDB->visitSPDescriptorParent(SDB->SPDescriptor, ParentMBB); CurDAG->setRoot(SDB->getRoot()); SDB->clear(); @@ -1759,7 +1800,7 @@ SelectionDAGISel::FinishBasicBlock() { // register allocation issues caused by us splitting the parent mbb. The // register allocator will clean up said virtual copies later on. MachineBasicBlock::iterator SplitPoint = - FindSplitPointForStackProtector(ParentMBB); + FindSplitPointForStackProtector(ParentMBB, *TII); // Splice the terminator of ParentMBB into SuccessMBB. SuccessMBB->splice(SuccessMBB->end(), ParentMBB, @@ -2293,6 +2334,11 @@ void SelectionDAGISel::Select_FREEZE(SDNode *N) { N->getOperand(0)); } +void SelectionDAGISel::Select_ARITH_FENCE(SDNode *N) { + CurDAG->SelectNodeTo(N, TargetOpcode::ARITH_FENCE, N->getValueType(0), + N->getOperand(0)); +} + /// GetVBR - decode a vbr encoding whose top bit is set. LLVM_ATTRIBUTE_ALWAYS_INLINE static uint64_t GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) { @@ -2579,6 +2625,17 @@ CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex, return VT == MVT::iPTR && cast<VTSDNode>(N)->getVT() == TLI->getPointerTy(DL); } +// Bit 0 stores the sign of the immediate. The upper bits contain the magnitude +// shifted left by 1. +static uint64_t decodeSignRotatedValue(uint64_t V) { + if ((V & 1) == 0) + return V >> 1; + if (V != 1) + return -(V >> 1); + // There is no such thing as -0 with integers. "-0" really means MININT. + return 1ULL << 63; +} + LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N) { @@ -2586,6 +2643,8 @@ CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex, if (Val & 128) Val = GetVBR(Val, MatcherTable, MatcherIndex); + Val = decodeSignRotatedValue(Val); + ConstantSDNode *C = dyn_cast<ConstantSDNode>(N); return C && C->getSExtValue() == Val; } @@ -2831,6 +2890,9 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, case ISD::FREEZE: Select_FREEZE(NodeToMatch); return; + case ISD::ARITH_FENCE: + Select_ARITH_FENCE(NodeToMatch); + return; } assert(!NodeToMatch->isMachineOpcode() && "Node already selected!"); @@ -3239,12 +3301,15 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, continue; } - case OPC_EmitInteger: { + case OPC_EmitInteger: + case OPC_EmitStringInteger: { MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++]; int64_t Val = MatcherTable[MatcherIndex++]; if (Val & 128) Val = GetVBR(Val, MatcherTable, MatcherIndex); + if (Opcode == OPC_EmitInteger) + Val = decodeSignRotatedValue(Val); RecordedNodes.push_back(std::pair<SDValue, SDNode*>( CurDAG->getTargetConstant(Val, SDLoc(NodeToMatch), VT), nullptr)); @@ -3729,7 +3794,7 @@ void SelectionDAGISel::CannotYetSelect(SDNode *N) { unsigned iid = cast<ConstantSDNode>(N->getOperand(HasInputChain))->getZExtValue(); if (iid < Intrinsic::num_intrinsics) - Msg << "intrinsic %" << Intrinsic::getName((Intrinsic::ID)iid, None); + Msg << "intrinsic %" << Intrinsic::getBaseName((Intrinsic::ID)iid); else if (const TargetIntrinsicInfo *TII = TM.getIntrinsicInfo()) Msg << "target intrinsic %" << TII->getName(iid); else |
