diff options
author | Evan Cheng <evan.cheng@apple.com> | 2012-10-05 01:48:22 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2012-10-05 01:48:22 +0000 |
commit | 2a2947885aea4e96eb6b776c1558f625506a26d2 (patch) | |
tree | 830efc9ca51a00f341e89699c55a43d7aa46a703 /lib/Target | |
parent | fca3f4021ae9a561edb6d2fcb4a282b6f25ab144 (diff) |
Follow up to r165072. Try a different approach: only move the load when it's going to be folded into the call. rdar://12437604
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165287 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 98778c3091..b79dd99d8f 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -387,21 +387,12 @@ static void MoveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load, CurDAG->UpdateNodeOperands(Load.getNode(), Call.getOperand(0), Load.getOperand(1), Load.getOperand(2)); - bool IsGlued = Call.getOperand(0).getNode()->getGluedUser() == Call.getNode(); unsigned NumOps = Call.getNode()->getNumOperands(); Ops.clear(); Ops.push_back(SDValue(Load.getNode(), 1)); for (unsigned i = 1, e = NumOps; i != e; ++i) Ops.push_back(Call.getOperand(i)); - if (!IsGlued) - CurDAG->UpdateNodeOperands(Call.getNode(), &Ops[0], NumOps); - else - // If call's chain was glued to the call (tailcall), and now the load - // is moved between them. Remove the glue to avoid a cycle (where the - // call is glued to its old chain and the load is using the old chain - // as its new chain). - CurDAG->MorphNodeTo(Call.getNode(), Call.getOpcode(), - Call.getNode()->getVTList(), &Ops[0], NumOps-1); + CurDAG->UpdateNodeOperands(Call.getNode(), &Ops[0], NumOps); } /// isCalleeLoad - Return true if call address is a load and it can be @@ -410,6 +401,10 @@ static void MoveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load, /// In the case of a tail call, there isn't a callseq node between the call /// chain and the load. static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq) { + // The transformation is somewhat dangerous if the call's chain was glued to + // the call. After MoveBelowOrigChain the load is moved between the call and + // the chain, this can create a cycle if the load is not folded. So it is + // *really* important that we are sure the load will be folded. if (Callee.getNode() == Chain.getNode() || !Callee.hasOneUse()) return false; LoadSDNode *LD = dyn_cast<LoadSDNode>(Callee.getNode()); @@ -447,7 +442,10 @@ void X86DAGToDAGISel::PreprocessISelDAG() { if (OptLevel != CodeGenOpt::None && (N->getOpcode() == X86ISD::CALL || - N->getOpcode() == X86ISD::TC_RETURN)) { + (N->getOpcode() == X86ISD::TC_RETURN && + // Only does this if load can be foled into TC_RETURN. + (Subtarget->is64Bit() || + getTargetMachine().getRelocationModel() != Reloc::PIC_)))) { /// Also try moving call address load from outside callseq_start to just /// before the call to allow it to be folded. /// |