aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp85
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