Skip moving call address loading into callseq when targets prefer register indirect...
authorMichael Liao <michael.liao@intel.com>
Thu, 28 Mar 2013 23:13:21 +0000 (23:13 +0000)
committerMichael Liao <michael.liao@intel.com>
Thu, 28 Mar 2013 23:13:21 +0000 (23:13 +0000)
To enable a load of a call address to be folded with that call, this
load is moved from outside of callseq into callseq. Such a moving
adds a non-glued node (that load) into a glued sequence. This non-glue
load is only removed when DAG selection folds them into a memory form
call instruction. When such instruction selection is disabled, it breaks
DAG schedule.

To prevent that, such moving is disabled when target favors register
indirect call.

Previous workaround disabling CALL32m/CALL64m insn selection is removed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178308 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelDAGToDAG.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86InstrControl.td
lib/Target/X86/X86InstrInfo.td

index 00fbe6924cc244659aa24651897d60c7bc3c50d1..6041669f81825b746c279bd0bc9d7f57d6324a0e 100644 (file)
@@ -444,7 +444,9 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
     SDNode *N = I++;  // Preincrement iterator to avoid invalidation issues.
 
     if (OptLevel != CodeGenOpt::None &&
-        (N->getOpcode() == X86ISD::CALL ||
+        // Only does this when target favors doesn't favor register indirect
+        // call.
+        ((N->getOpcode() == X86ISD::CALL && !Subtarget->callRegIndirect()) ||
          (N->getOpcode() == X86ISD::TC_RETURN &&
           // Only does this if load can be folded into TC_RETURN.
           (Subtarget->is64Bit() ||
index bff5426f90874b9b66b37f59604b5da47aae5267..709e9e8aaeeecc718762bbe79633183187e03e79 100644 (file)
@@ -2634,19 +2634,6 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
     InFlag = Chain.getValue(1);
   }
 
-  // Use indirect reference through register, when CALL uses a memory reference.
-  if (Subtarget->callRegIndirect() &&
-      Callee.getOpcode() == ISD::LOAD) {
-    const TargetRegisterClass *AddrRegClass =
-      getRegClassFor(Subtarget->is64Bit() ? MVT::i64:MVT::i32);
-    MachineRegisterInfo &MRI = MF.getRegInfo();
-    unsigned VReg = MRI.createVirtualRegister(AddrRegClass);
-    SDValue tempValue = DAG.getCopyFromReg(Callee,
-                                           dl, VReg, Callee.getValueType());
-    Chain = DAG.getCopyToReg(Chain, dl, VReg, tempValue, InFlag);
-    InFlag = Chain.getValue(1);
-  }
-
   Ops.push_back(Chain);
   Ops.push_back(Callee);
 
index 1027dedcec40cdde221e27792c3f77e8978ce02b..0e696513d47c45f07a3a7968671f4cbc644dc51d 100644 (file)
@@ -170,7 +170,8 @@ let isCall = 1 in
     def CALL32m     : I<0xFF, MRM2m, (outs), (ins i32mem:$dst),
                         "call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))],
                         IIC_CALL_MEM>,
-                      Requires<[In32BitMode]>, Sched<[WriteJumpLd]>;
+                      Requires<[In32BitMode,FavorMemIndirectCall]>,
+                      Sched<[WriteJumpLd]>;
 
     def FARCALL16i  : Iseg16<0x9A, RawFrmImm16, (outs),
                              (ins i16imm:$off, i16imm:$seg),
@@ -245,7 +246,7 @@ let isCall = 1, Uses = [RSP], SchedRW = [WriteJump] in {
   def CALL64m       : I<0xFF, MRM2m, (outs), (ins i64mem:$dst),
                         "call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))],
                         IIC_CALL_MEM>,
-                      Requires<[In64BitMode]>;
+                      Requires<[In64BitMode,FavorMemIndirectCall]>;
 
   def FARCALL64   : RI<0xFF, MRM3m, (outs), (ins opaque80mem:$dst),
                        "lcall{q}\t{*}$dst", [], IIC_CALL_FAR_MEM>;
index 359c507d472e3bcd6c62e42651584513a82ce071..93e8beb19bea36b14c9bfd88d3ba2873d329fc6b 100644 (file)
@@ -630,6 +630,7 @@ def OptForSize   : Predicate<"OptForSize">;
 def OptForSpeed  : Predicate<"!OptForSize">;
 def FastBTMem    : Predicate<"!Subtarget->isBTMemSlow()">;
 def CallImmAddr  : Predicate<"Subtarget->IsLegalToCallImmediateAddr(TM)">;
+def FavorMemIndirectCall  : Predicate<"!Subtarget->callRegIndirect()">;
 
 //===----------------------------------------------------------------------===//
 // X86 Instruction Format Definitions.