* Removed the use of FLAG. Now use hasFlagIn and hasFlagOut instead.
authorEvan Cheng <evan.cheng@apple.com>
Fri, 23 Dec 2005 22:14:32 +0000 (22:14 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 23 Dec 2005 22:14:32 +0000 (22:14 +0000)
* Added a pseudo instruction (for each target) that represent "return void".
  This is a workaround for lack of optional flag operand (return void is not
  lowered so it does not have a flag operand.)

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

lib/Target/PowerPC/PPCInstrInfo.td
lib/Target/PowerPC/PPCRegisterInfo.cpp
lib/Target/Sparc/SparcInstrInfo.td
lib/Target/Sparc/SparcRegisterInfo.cpp
lib/Target/SparcV8/SparcV8InstrInfo.td
lib/Target/SparcV8/SparcV8RegisterInfo.cpp
lib/Target/Target.td
lib/Target/TargetSelectionDAG.td
lib/Target/X86/X86InstrInfo.td
lib/Target/X86/X86RegisterInfo.cpp

index f78cbbbe37b06fb0d37ab06c6ee53d904c100c1d..55eea5fcd46d154a1a1d8ee250982924cdc097ce 100644 (file)
@@ -46,7 +46,7 @@ def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeq,[SDNPHasChain]>;
 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_PPCCallSeq,[SDNPHasChain]>;
 
-def SDT_PPCRetFlag : SDTypeProfile<0, 1, [ SDTCisVT<0, FlagVT>]>;
+def SDT_PPCRetFlag : SDTypeProfile<0, 0, []>;
 def retflag       : SDNode<"PPCISD::RET_FLAG", SDT_PPCRetFlag, [SDNPHasChain]>;
 
 //===----------------------------------------------------------------------===//
@@ -223,8 +223,11 @@ let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
 
 
 let isTerminator = 1 in {
+  // FIXME: temporary workaround for return without an incoming flag.
   let isReturn = 1 in
-    def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(ret)]>;
+    def BLRVOID : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, [(ret)]>;
+  let isReturn = 1, hasInFlag = 1 in
+    def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (ops), "blr", BrB, []>;
   def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (ops), "bctr", BrB, []>;
 }
 
@@ -1056,7 +1059,7 @@ def : Pat<(f64 (extload iaddr:$src, f32)),
 def : Pat<(f64 (extload xaddr:$src, f32)),
           (FMRSD (LFSX xaddr:$src))>;
 
-def : Pat<(retflag FLAG), (BLR)>;
+def : Pat<(retflag), (BLR)>;
 
 // Same as above, but using a temporary. FIXME: implement temporaries :)
 /*
index ae136cbc420a58bc449b1f55798a26973e78ff2c..494bedaf44133f28cc5c1edb674da6ee74728a19 100644 (file)
@@ -373,7 +373,8 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
   const MachineFrameInfo *MFI = MF.getFrameInfo();
   MachineBasicBlock::iterator MBBI = prior(MBB.end());
   MachineInstr *MI;
-  assert(MBBI->getOpcode() == PPC::BLR &&
+  // FIXME: BLRVOID should be removed. See PPCInstrInfo.td
+  assert((MBBI->getOpcode() == PPC::BLR || MBBI->getOpcode() == PPC::BLRVOID) &&
          "Can only insert epilog into returning blocks");
 
   // Get the number of bytes allocated from the FrameInfo...
index cccf6f1ad0db7ad88f4fb51ba111bec60059508d..79c054eab57e648a29acd6b8f4f48bf84a53d92c 100644 (file)
@@ -93,11 +93,10 @@ def SDT_V8CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>;
 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_V8CallSeq, [SDNPHasChain]>;
 
-def SDT_V8Call    : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisVT<1, i32>,
-                                         SDTCisVT<2, FlagVT>]>;
+def SDT_V8Call    : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
 def call          : SDNode<"ISD::CALL", SDT_V8Call, [SDNPHasChain]>;
 
-def SDT_V8RetFlag : SDTypeProfile<0, 1, [ SDTCisVT<0, FlagVT>]>;
+def SDT_V8RetFlag : SDTypeProfile<0, 0, []>;
 def retflag       : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag, [SDNPHasChain]>;
 
 //===----------------------------------------------------------------------===//
@@ -174,8 +173,10 @@ let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
 // special cases of JMPL:
 let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
   let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
-    def RETL: F3_2<2, 0b111000, (ops),
-                   "retl", [(ret)]>;
+    // FIXME: temporary workaround for return without an incoming flag.
+    def RETVOID: F3_2<2, 0b111000, (ops), "retl", [(ret)]>;
+    let hasInFlag = 1 in
+      def RETL: F3_2<2, 0b111000, (ops), "retl", []>;
 }
 
 // Section B.1 - Load Integer Instructions, p. 90
@@ -559,27 +560,26 @@ def FBO  : FPBranchV8<0b1111, (ops brtarget:$dst),
 
 // Section B.24 - Call and Link Instruction, p. 125
 // This is the only Format 1 instruction
-let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1,
+let Uses = [O0, O1, O2, O3, O4, O5],
+    hasDelaySlot = 1, isCall = 1, hasInFlag = 1, hasOutFlag = 1,
     Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
     D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { 
-  // pc-relative call:
   def CALL : InstV8<(ops calltarget:$dst),
-                    "call $dst",
-                  [(set FLAG, (call tglobaladdr:$dst, FLAG))]> {
+                    "call $dst", []> {
     bits<30> disp;
     let op = 1;
     let Inst{29-0} = disp;
   }
-
+  
   // indirect calls
   def JMPLrr : F3_1<2, 0b111000,
                     (ops MEMrr:$ptr),
                     "call $ptr",
-                    [(set FLAG, (call  ADDRrr:$ptr, FLAG))]>;
+                    [(call  ADDRrr:$ptr)]>;
   def JMPLri : F3_2<2, 0b111000,
                     (ops MEMri:$ptr),
                     "call $ptr",
-                    [(set FLAG, (call  ADDRri:$ptr, FLAG))]>;
+                    [(call  ADDRri:$ptr)]>;
 }
 
 // Section B.28 - Read State Register Instructions
@@ -724,7 +724,15 @@ def : Pat<(V8hi tconstpool:$in), (SETHIi tconstpool:$in)>;
 def : Pat<(V8lo tconstpool:$in), (ORri G0, tconstpool:$in)>;
 
 // Return of a value, which has an input flag.
-def : Pat<(retflag FLAG), (RETL)>;
+def : Pat<(retflag), (RETL)>;
+
+
+// Calls: 
+def : Pat<(call tglobaladdr:$dst),
+          (CALL tglobaladdr:$dst)>;
+def : Pat<(call externalsym:$dst),
+          (CALL externalsym:$dst)>;
+
 
 // Map integer extload's to zextloads.
 def : Pat<(i32 (extload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
index 49cbbc091d7ee3fd7752791fde31d28c72cca651..f33e5c32e38b2522b34438f8fc77cad4b33db837 100644 (file)
@@ -165,7 +165,8 @@ void SparcV8RegisterInfo::emitPrologue(MachineFunction &MF) const {
 void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF,
                                        MachineBasicBlock &MBB) const {
   MachineBasicBlock::iterator MBBI = prior(MBB.end());
-  assert(MBBI->getOpcode() == V8::RETL &&
+  // FIXME: RETVOID should be removed. See SparcV8InstrInfo.td
+  assert((MBBI->getOpcode() == V8::RETL || MBBI->getOpcode() == V8::RETVOID) &&
          "Can only put epilog before 'retl' instruction!");
   BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0);
 }
index cccf6f1ad0db7ad88f4fb51ba111bec60059508d..79c054eab57e648a29acd6b8f4f48bf84a53d92c 100644 (file)
@@ -93,11 +93,10 @@ def SDT_V8CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>;
 def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_V8CallSeq, [SDNPHasChain]>;
 
-def SDT_V8Call    : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisVT<1, i32>,
-                                         SDTCisVT<2, FlagVT>]>;
+def SDT_V8Call    : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
 def call          : SDNode<"ISD::CALL", SDT_V8Call, [SDNPHasChain]>;
 
-def SDT_V8RetFlag : SDTypeProfile<0, 1, [ SDTCisVT<0, FlagVT>]>;
+def SDT_V8RetFlag : SDTypeProfile<0, 0, []>;
 def retflag       : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag, [SDNPHasChain]>;
 
 //===----------------------------------------------------------------------===//
@@ -174,8 +173,10 @@ let usesCustomDAGSchedInserter = 1 in {  // Expanded by the scheduler.
 // special cases of JMPL:
 let isReturn = 1, isTerminator = 1, hasDelaySlot = 1 in {
   let rd = O7.Num, rs1 = G0.Num, simm13 = 8 in
-    def RETL: F3_2<2, 0b111000, (ops),
-                   "retl", [(ret)]>;
+    // FIXME: temporary workaround for return without an incoming flag.
+    def RETVOID: F3_2<2, 0b111000, (ops), "retl", [(ret)]>;
+    let hasInFlag = 1 in
+      def RETL: F3_2<2, 0b111000, (ops), "retl", []>;
 }
 
 // Section B.1 - Load Integer Instructions, p. 90
@@ -559,27 +560,26 @@ def FBO  : FPBranchV8<0b1111, (ops brtarget:$dst),
 
 // Section B.24 - Call and Link Instruction, p. 125
 // This is the only Format 1 instruction
-let Uses = [O0, O1, O2, O3, O4, O5], hasDelaySlot = 1, isCall = 1,
+let Uses = [O0, O1, O2, O3, O4, O5],
+    hasDelaySlot = 1, isCall = 1, hasInFlag = 1, hasOutFlag = 1,
     Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7,
     D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { 
-  // pc-relative call:
   def CALL : InstV8<(ops calltarget:$dst),
-                    "call $dst",
-                  [(set FLAG, (call tglobaladdr:$dst, FLAG))]> {
+                    "call $dst", []> {
     bits<30> disp;
     let op = 1;
     let Inst{29-0} = disp;
   }
-
+  
   // indirect calls
   def JMPLrr : F3_1<2, 0b111000,
                     (ops MEMrr:$ptr),
                     "call $ptr",
-                    [(set FLAG, (call  ADDRrr:$ptr, FLAG))]>;
+                    [(call  ADDRrr:$ptr)]>;
   def JMPLri : F3_2<2, 0b111000,
                     (ops MEMri:$ptr),
                     "call $ptr",
-                    [(set FLAG, (call  ADDRri:$ptr, FLAG))]>;
+                    [(call  ADDRri:$ptr)]>;
 }
 
 // Section B.28 - Read State Register Instructions
@@ -724,7 +724,15 @@ def : Pat<(V8hi tconstpool:$in), (SETHIi tconstpool:$in)>;
 def : Pat<(V8lo tconstpool:$in), (ORri G0, tconstpool:$in)>;
 
 // Return of a value, which has an input flag.
-def : Pat<(retflag FLAG), (RETL)>;
+def : Pat<(retflag), (RETL)>;
+
+
+// Calls: 
+def : Pat<(call tglobaladdr:$dst),
+          (CALL tglobaladdr:$dst)>;
+def : Pat<(call externalsym:$dst),
+          (CALL externalsym:$dst)>;
+
 
 // Map integer extload's to zextloads.
 def : Pat<(i32 (extload ADDRrr:$src, i1)), (LDUBrr ADDRrr:$src)>;
index 49cbbc091d7ee3fd7752791fde31d28c72cca651..f33e5c32e38b2522b34438f8fc77cad4b33db837 100644 (file)
@@ -165,7 +165,8 @@ void SparcV8RegisterInfo::emitPrologue(MachineFunction &MF) const {
 void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF,
                                        MachineBasicBlock &MBB) const {
   MachineBasicBlock::iterator MBBI = prior(MBB.end());
-  assert(MBBI->getOpcode() == V8::RETL &&
+  // FIXME: RETVOID should be removed. See SparcV8InstrInfo.td
+  assert((MBBI->getOpcode() == V8::RETL || MBBI->getOpcode() == V8::RETVOID) &&
          "Can only put epilog before 'retl' instruction!");
   BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0);
 }
index 69b6baf28e9051b2f53682f746cecfb9abb910dc..f2b98ad499561a103c76f0e12c8778bf1117034b 100644 (file)
@@ -169,6 +169,8 @@ class Instruction {
   bit hasDelaySlot = 0;     // Does this instruction have an delay slot?
   bit usesCustomDAGSchedInserter = 0; // Pseudo instr needing special help.
   bit hasCtrlDep   = 0;     // Does this instruction r/w ctrl-flow chains?
+  bit hasInFlag    = 0;     // Does this instruction read a flag operand?
+  bit hasOutFlag   = 0;     // Does this instruction write a flag operand?
   
   InstrItinClass Itinerary; // Execution steps used for scheduling. 
 }
index afe7de185d8c7baaae2d2957f55325f6a3d13e54..2d6f4e344c22fb57850a61175df9090cf42ac291 100644 (file)
@@ -184,7 +184,6 @@ class SDNode<string opcode, SDTypeProfile typeprof,
 def set;
 def node;
 def srcvalue;
-def FLAG;
 
 def imm        : SDNode<"ISD::Constant"  , SDTIntLeaf , [], "ConstantSDNode">;
 def vt         : SDNode<"ISD::VALUETYPE" , SDTOther   , [], "VTSDNode">;
index cf40cb0a08cb9d5fcd86223b07b6de01781999b1..f69162e23f2567101c8a30158cfa7fffa9ff7205 100644 (file)
@@ -32,13 +32,12 @@ def SDTX86SetCC   : SDTypeProfile<1, 2,
                                   [SDTCisVT<0, i8>, SDTCisVT<1, OtherVT>,
                                    SDTCisVT<2, FlagVT>]>;
 
-def SDTX86RetFlag : SDTypeProfile<0, 2, [SDTCisVT<0, i16>,
-                                         SDTCisVT<1, FlagVT>]>;
+def SDTX86RetFlag : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>;
 
 def SDTX86Fld     : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
                                          SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
 
-def SDTX86FpSet   : SDTypeProfile<1, 1, [SDTCisVT<0, FlagVT>, SDTCisFP<1>]>;
+def SDTX86FpSet   : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
 
 def X86cmp     : SDNode<"X86ISD::CMP" ,     SDTX86CmpTest,  []>;
 def X86test    : SDNode<"X86ISD::TEST",     SDTX86CmpTest,  []>;
@@ -47,7 +46,7 @@ def X86cmov    : SDNode<"X86ISD::CMOV",     SDTX86Cmov,     []>;
 def X86Brcond  : SDNode<"X86ISD::BRCOND",   SDTX86BrCond,   [SDNPHasChain]>;
 def X86SetCC   : SDNode<"X86ISD::SETCC",    SDTX86SetCC,    []>;
 
-def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>;
+def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag,  [SDNPHasChain]>;
 
 def X86fld     : SDNode<"X86ISD::FLD",      SDTX86Fld,      [SDNPHasChain]>;
 
@@ -290,13 +289,17 @@ let isTerminator = 1 in
 //
 
 // Return instructions.
-let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in
-  def RET : I<0xC3, RawFrm, (ops), "ret", [(ret)]>;
-let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in
-  def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>;
+let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
+  // FIXME: temporary workaround for return without an incoming flag.
+  def RETVOID : I<0xC3, RawFrm, (ops), "ret", [(ret)]>;
+  let hasInFlag = 1 in {
+    def RET : I<0xC3, RawFrm, (ops), "ret", []>;
+    def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>;
+  }
+}
 
-def : Pat<(X86retflag 0, FLAG),        (RET)>;
-def : Pat<(X86retflag imm:$amt, FLAG), (RETI imm:$amt)>;
+def : Pat<(X86retflag 0),        (RET)>;
+def : Pat<(X86retflag imm:$amt), (RETI imm:$amt)>;
 
 // All branches are RawFrm, Void, Branch, and Terminators
 let isBranch = 1, isTerminator = 1 in
@@ -2312,17 +2315,14 @@ class FpPseudoI<dag ops, FPFormat fp, list<dag> pattern>
 }
 
 // Random Pseudo Instructions.
-def FpGETRESULT : FpPseudoI<(ops RFP:$dst), SpecialFP, // FPR = ST(0)
-                      []>;  
-def FpSETRESULT : FpPseudoI<(ops RFP:$src), SpecialFP,
-                      [(set FLAG, (X86fpset RFP:$src))]>,
-                       Imp<[], [ST0]>;  // ST(0) = FPR
+def FpGETRESULT : FpPseudoI<(ops RFP:$dst), SpecialFP, []>;     // FPR = ST(0)
+let hasOutFlag = 1 in 
+  def FpSETRESULT : FpPseudoI<(ops RFP:$src), SpecialFP,
+                    [(X86fpset RFP:$src)]>, Imp<[], [ST0]>;     // ST(0) = FPR
 
-def FpMOV       : FpI<(ops RFP:$dst, RFP:$src), SpecialFP,
-                      []>;   // f1 = fmov f2
+def FpMOV       : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2
 
 // Arithmetic
-
 // Add, Sub, Mul, Div.
 def FpADD : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), TwoArgFP,
                 [(set RFP:$dst, (fadd RFP:$src1, RFP:$src2))]>;
index 765b657d0659297b9f1879d145dc3b7e54d9123d..73026bbfda431782b2184285b6fbf8310a87ae07 100644 (file)
@@ -568,6 +568,7 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
   switch (MBBI->getOpcode()) {
   case X86::RET:
   case X86::RETI:
+  case X86::RETVOID:  // FIXME: See X86InstrInfo.td
   case X86::TAILJMPd:
   case X86::TAILJMPr:
   case X86::TAILJMPm: break;  // These are ok