[llvm-commits] [llvm] r45829 - in /llvm/trunk: lib/Target/Target.td lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrFPStack.td lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86InstrMMX.td lib/Target/X86/X86InstrSSE.td utils/TableGen/CodeGenInstruction.cpp utils/TableGen/CodeGenInstruction.h utils/TableGen/CodeGenTarget.cpp utils/TableGen/InstrInfoEmitter.cpp

Chris Lattner sabre at nondot.org
Wed Jan 9 23:59:24 PST 2008


Author: lattner
Date: Thu Jan 10 01:59:24 2008
New Revision: 45829

URL: http://llvm.org/viewvc/llvm-project?rev=45829&view=rev
Log:
Start inferring side effect information more aggressively, and fix many bugs in the
x86 backend where instructions were not marked maystore/mayload, and perf issues where
instructions were not marked neverHasSideEffects.  It would be really nice if we could
write patterns for copy instructions.

I have audited all the x86 instructions down to MOVDQAmr.  The flags on others and on
other targets are probably not right in all cases, but no clients currently use this
info that are enabled by default.

Modified:
    llvm/trunk/lib/Target/Target.td
    llvm/trunk/lib/Target/X86/X86Instr64bit.td
    llvm/trunk/lib/Target/X86/X86InstrFPStack.td
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/lib/Target/X86/X86InstrMMX.td
    llvm/trunk/lib/Target/X86/X86InstrSSE.td
    llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
    llvm/trunk/utils/TableGen/CodeGenInstruction.h
    llvm/trunk/utils/TableGen/CodeGenTarget.cpp
    llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp

Modified: llvm/trunk/lib/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Target.td?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Target.td (original)
+++ llvm/trunk/lib/Target/Target.td Thu Jan 10 01:59:24 2008
@@ -204,19 +204,20 @@
   bit hasCtrlDep   = 0;     // Does this instruction r/w ctrl-flow chains?
   bit isNotDuplicable = 0;  // Is it unsafe to duplicate this instruction?
 
-  // Side effect flags - If neither of these flags is set, then the instruction
-  // *always* has side effects. When set, the flags have these meanings:
+  // Side effect flags - When set, the flags have these meanings:
   //
-  //  neverHasSideEffects - The instruction has no side effects that are not
-  //    captured by any operands of the instruction or other flags, and when
-  //    *all* instances of the instruction of that opcode have no side effects.
+  //  hasSideEffects - The instruction has side effects that are not
+  //    captured by any operands of the instruction or other flags.
   //  mayHaveSideEffects  - Some instances of the instruction can have side
   //    effects. The virtual method "isReallySideEffectFree" is called to
   //    determine this. Load instructions are an example of where this is
   //    useful. In general, loads always have side effects. However, loads from
   //    constant pools don't. Individual back ends make this determination.
-  bit neverHasSideEffects = 0;
+  //  neverHasSideEffects - Set on an instruction with no pattern if it has no
+  //    side effects.
+  bit hasSideEffects = 0;
   bit mayHaveSideEffects = 0;
+  bit neverHasSideEffects = 0;
   
   InstrItinClass Itinerary = NoItinerary;// Execution steps used for scheduling.
 
@@ -343,12 +344,14 @@
   let InOperandList = (ops variable_ops);
   let AsmString = "";
   let Namespace = "TargetInstrInfo";
+  let neverHasSideEffects = 1;
 }
 def INSERT_SUBREG : Instruction {
         let OutOperandList = (ops variable_ops);
   let InOperandList = (ops variable_ops);
   let AsmString = "";
   let Namespace = "TargetInstrInfo";
+  let neverHasSideEffects = 1;
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original)
+++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Thu Jan 10 01:59:24 2008
@@ -131,19 +131,21 @@
 //===----------------------------------------------------------------------===//
 //  Miscellaneous Instructions...
 //
-let Defs = [RBP,RSP], Uses = [RBP,RSP] in
+let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in
 def LEAVE64  : I<0xC9, RawFrm,
                  (outs), (ins), "leave", []>;
-let Defs = [RSP], Uses = [RSP] in {
+let Defs = [RSP], Uses = [RSP], neverHasSideEffects=1 in {
+let mayLoad = 1 in
 def POP64r   : I<0x58, AddRegFrm,
                  (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
+let mayStore = 1 in
 def PUSH64r  : I<0x50, AddRegFrm,
                  (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
 }
 
-let Defs = [RSP, EFLAGS], Uses = [RSP] in
+let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in
 def POPFQ    : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W;
-let Defs = [RSP], Uses = [RSP, EFLAGS] in
+let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in
 def PUSHFQ   : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
 
 def LEA64_32r : I<0x8D, MRMSrcMem,
@@ -160,12 +162,16 @@
                   "bswap{q}\t$dst", 
                   [(set GR64:$dst, (bswap GR64:$src))]>, TB;
 // Exchange
+let neverHasSideEffects = 1 in {
 def XCHG64rr : RI<0x87, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
                   "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>;
+let mayLoad = 1, mayStore = 1 in {
 def XCHG64mr : RI<0x87, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
                   "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>;
 def XCHG64rm : RI<0x87, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2),
                   "xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>;
+}
+}
 
 // Bit scan instructions.
 let Defs = [EFLAGS] in {
@@ -198,6 +204,7 @@
 //  Move Instructions...
 //
 
+let neverHasSideEffects = 1 in
 def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
                  "mov{q}\t{$src, $dst|$dst, $src}", []>;
 
@@ -256,13 +263,15 @@
                     "movz{wq|x}\t{$src, $dst|$dst, $src}",
                     [(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
 
-let Defs = [RAX], Uses = [EAX] in
-def CDQE : RI<0x98, RawFrm, (outs), (ins),
-             "{cltq|cdqe}", []>;     // RAX = signext(EAX)
-
-let Defs = [RAX,RDX], Uses = [RAX] in
-def CQO  : RI<0x99, RawFrm, (outs), (ins),
-              "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
+let neverHasSideEffects = 1 in {
+  let Defs = [RAX], Uses = [EAX] in
+  def CDQE : RI<0x98, RawFrm, (outs), (ins),
+               "{cltq|cdqe}", []>;     // RAX = signext(EAX)
+
+  let Defs = [RAX,RDX], Uses = [RAX] in
+  def CQO  : RI<0x99, RawFrm, (outs), (ins),
+                "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
+}
 
 //===----------------------------------------------------------------------===//
 //  Arithmetic Instructions...
@@ -387,15 +396,17 @@
 } // Defs = [EFLAGS]
 
 // Unsigned multiplication
-let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in {
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], neverHasSideEffects = 1 in {
 def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
                 "mul{q}\t$src", []>;         // RAX,RDX = RAX*GR64
+let mayLoad = 1 in
 def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
                 "mul{q}\t$src", []>;         // RAX,RDX = RAX*[mem64]
 
 // Signed multiplication
 def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src),
                  "imul{q}\t$src", []>;         // RAX,RDX = RAX*GR64
+let mayLoad = 1 in
 def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
                  "imul{q}\t$src", []>;         // RAX,RDX = RAX*[mem64]
 }
@@ -432,18 +443,21 @@
 } // Defs = [EFLAGS]
 
 // Unsigned division / remainder
+let neverHasSideEffects = 1 in {
 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in {
 def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),        // RDX:RAX/r64 = RAX,RDX
                 "div{q}\t$src", []>;
-def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),      // RDX:RAX/[mem64] = RAX,RDX
-                "div{q}\t$src", []>;
-
 // Signed division / remainder
 def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),        // RDX:RAX/r64 = RAX,RDX
                 "idiv{q}\t$src", []>;
+let mayLoad = 1 in {
+def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),      // RDX:RAX/[mem64] = RAX,RDX
+                "div{q}\t$src", []>;
 def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),      // RDX:RAX/[mem64] = RAX,RDX
                 "idiv{q}\t$src", []>;
 }
+}
+}
 
 // Unary instructions
 let Defs = [EFLAGS], CodeSize = 2 in {
@@ -1035,11 +1049,12 @@
 def CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem, (outs FR32:$dst), (ins i64mem:$src),
                        "cvtsi2ss{q}\t{$src, $dst|$dst, $src}",
                        [(set FR32:$dst, (sint_to_fp (loadi64 addr:$src)))]>;
-let isTwoAddress = 1 in {
+let isTwoAddress = 1, neverHasSideEffects = 1 in {
 def Int_CVTSI2SS64rr: RSSI<0x2A, MRMSrcReg,
                            (outs VR128:$dst), (ins VR128:$src1, GR64:$src2),
                            "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",
                            []>; // TODO: add intrinsic
+let mayLoad = 1 in 
 def Int_CVTSI2SS64rm: RSSI<0x2A, MRMSrcMem,
                            (outs VR128:$dst), (ins VR128:$src1, i64mem:$src2),
                            "cvtsi2ss{q}\t{$src2, $dst|$dst, $src2}",

Modified: llvm/trunk/lib/Target/X86/X86InstrFPStack.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFPStack.td?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFPStack.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFPStack.td Thu Jan 10 01:59:24 2008
@@ -32,25 +32,25 @@
 def SDTX86CwdStore  : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
 
 def X86fpget        : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet,
-                        [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
+                             [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
 def X86fpset        : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet,
-                        [SDNPHasChain, SDNPOutFlag]>;
-def X86fld          : SDNode<"X86ISD::FLD",      SDTX86Fld,
-                        [SDNPHasChain, SDNPMayLoad]>;
-def X86fst          : SDNode<"X86ISD::FST",      SDTX86Fst,
-                        [SDNPHasChain, SDNPInFlag, SDNPMayStore]>;
-def X86fild         : SDNode<"X86ISD::FILD",     SDTX86Fild,
-                        [SDNPHasChain, SDNPMayLoad]>;
-def X86fildflag     : SDNode<"X86ISD::FILD_FLAG",SDTX86Fild,
-                        [SDNPHasChain, SDNPOutFlag, SDNPMayLoad]>;
+                             [SDNPHasChain, SDNPOutFlag]>;
+def X86fld          : SDNode<"X86ISD::FLD", SDTX86Fld,
+                             [SDNPHasChain, SDNPMayLoad]>;
+def X86fst          : SDNode<"X86ISD::FST", SDTX86Fst,
+                             [SDNPHasChain, SDNPInFlag, SDNPMayStore]>;
+def X86fild         : SDNode<"X86ISD::FILD", SDTX86Fild,
+                             [SDNPHasChain, SDNPMayLoad]>;
+def X86fildflag     : SDNode<"X86ISD::FILD_FLAG", SDTX86Fild,
+                             [SDNPHasChain, SDNPOutFlag, SDNPMayLoad]>;
 def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem,
-                        [SDNPHasChain]>;
+                             [SDNPHasChain, SDNPMayStore]>;
 def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
-                        [SDNPHasChain]>;
+                             [SDNPHasChain, SDNPMayStore]>;
 def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
-                        [SDNPHasChain]>;
+                             [SDNPHasChain, SDNPMayStore]>;
 def X86fp_cwd_get16 : SDNode<"X86ISD::FNSTCW16m",          SDTX86CwdStore,
-                        [SDNPHasChain]>;
+                             [SDNPHasChain, SDNPMayStore, SDNPSideEffect]>;
 
 //===----------------------------------------------------------------------===//
 // FPStack pattern fragments
@@ -208,9 +208,9 @@
                   [(set RFP80:$dst, 
                     (OpNode RFP80:$src1, (f80 (extloadf64 addr:$src2))))]>;
 def _F32m  : FPI<0xD8, fp, (outs), (ins f32mem:$src), 
-                 !strconcat("f", !strconcat(asmstring, "{s}\t$src"))>;
+                 !strconcat("f", !strconcat(asmstring, "{s}\t$src"))> { let mayLoad = 1; }
 def _F64m  : FPI<0xDC, fp, (outs), (ins f64mem:$src), 
-                 !strconcat("f", !strconcat(asmstring, "{l}\t$src"))>;
+                 !strconcat("f", !strconcat(asmstring, "{l}\t$src"))> { let mayLoad = 1; }
 // ST(0) = ST(0) + [memint]
 def _FpI16m32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src1, i16mem:$src2), OneArgFPRW,
                     [(set RFP32:$dst, (OpNode RFP32:$src1,
@@ -231,9 +231,9 @@
                     [(set RFP80:$dst, (OpNode RFP80:$src1,
                                        (X86fild addr:$src2, i32)))]>;
 def _FI16m  : FPI<0xDE, fp, (outs), (ins i16mem:$src), 
-                  !strconcat("fi", !strconcat(asmstring, "{s}\t$src"))>;
+                  !strconcat("fi", !strconcat(asmstring, "{s}\t$src"))> { let mayLoad = 1; }
 def _FI32m  : FPI<0xDA, fp, (outs), (ins i32mem:$src), 
-                  !strconcat("fi", !strconcat(asmstring, "{l}\t$src"))>;
+                  !strconcat("fi", !strconcat(asmstring, "{l}\t$src"))> { let mayLoad = 1; }
 }
 
 defm ADD : FPBinary_rr<fadd>;
@@ -392,13 +392,16 @@
                   [(truncstoref64 RFP80:$src, addr:$op)]>;
 // FST does not support 80-bit memory target; FSTP must be used.
 
+let mayStore = 1 in {
 def ST_FpP32m    : FpIf32<(outs), (ins f32mem:$op, RFP32:$src), OneArgFP, []>;
 def ST_FpP64m32  : FpIf64<(outs), (ins f32mem:$op, RFP64:$src), OneArgFP, []>;
 def ST_FpP64m    : FpIf64<(outs), (ins f64mem:$op, RFP64:$src), OneArgFP, []>;
 def ST_FpP80m32  : FpI_<(outs), (ins f32mem:$op, RFP80:$src), OneArgFP, []>;
 def ST_FpP80m64  : FpI_<(outs), (ins f64mem:$op, RFP80:$src), OneArgFP, []>;
+}
 def ST_FpP80m    : FpI_<(outs), (ins f80mem:$op, RFP80:$src), OneArgFP,
                     [(store RFP80:$src, addr:$op)]>;
+let mayStore = 1 in {
 def IST_Fp16m32  : FpIf32<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP, []>;
 def IST_Fp32m32  : FpIf32<(outs), (ins i32mem:$op, RFP32:$src), OneArgFP, []>;
 def IST_Fp64m32  : FpIf32<(outs), (ins i64mem:$op, RFP32:$src), OneArgFP, []>;
@@ -408,13 +411,17 @@
 def IST_Fp16m80  : FpI_<(outs), (ins i16mem:$op, RFP80:$src), OneArgFP, []>;
 def IST_Fp32m80  : FpI_<(outs), (ins i32mem:$op, RFP80:$src), OneArgFP, []>;
 def IST_Fp64m80  : FpI_<(outs), (ins i64mem:$op, RFP80:$src), OneArgFP, []>;
+}
 
+let mayLoad = 1 in {
 def LD_F32m   : FPI<0xD9, MRM0m, (outs), (ins f32mem:$src), "fld{s}\t$src">;
 def LD_F64m   : FPI<0xDD, MRM0m, (outs), (ins f64mem:$src), "fld{l}\t$src">;
 def LD_F80m   : FPI<0xDB, MRM5m, (outs), (ins f80mem:$src), "fld{t}\t$src">;
 def ILD_F16m  : FPI<0xDF, MRM0m, (outs), (ins i16mem:$src), "fild{s}\t$src">;
 def ILD_F32m  : FPI<0xDB, MRM0m, (outs), (ins i32mem:$src), "fild{l}\t$src">;
 def ILD_F64m  : FPI<0xDF, MRM5m, (outs), (ins i64mem:$src), "fild{ll}\t$src">;
+}
+let mayStore = 1 in {
 def ST_F32m   : FPI<0xD9, MRM2m, (outs), (ins f32mem:$dst), "fst{s}\t$dst">;
 def ST_F64m   : FPI<0xDD, MRM2m, (outs), (ins f64mem:$dst), "fst{l}\t$dst">;
 def ST_FP32m  : FPI<0xD9, MRM3m, (outs), (ins f32mem:$dst), "fstp{s}\t$dst">;
@@ -425,6 +432,7 @@
 def IST_FP16m : FPI<0xDF, MRM3m, (outs), (ins i16mem:$dst), "fistp{s}\t$dst">;
 def IST_FP32m : FPI<0xDB, MRM3m, (outs), (ins i32mem:$dst), "fistp{l}\t$dst">;
 def IST_FP64m : FPI<0xDF, MRM7m, (outs), (ins i64mem:$dst), "fistp{ll}\t$dst">;
+}
 
 // FISTTP requires SSE3 even though it's a FPStack op.
 def ISTT_Fp16m32 : FpI_<(outs), (ins i16mem:$op, RFP32:$src), OneArgFP,
@@ -455,9 +463,11 @@
                     [(X86fp_to_i64mem RFP80:$src, addr:$op)]>,
                     Requires<[HasSSE3]>;
 
+let mayStore = 1 in {
 def ISTT_FP16m : FPI<0xDF, MRM1m, (outs), (ins i16mem:$dst), "fisttp{s}\t$dst">;
 def ISTT_FP32m : FPI<0xDB, MRM1m, (outs), (ins i32mem:$dst), "fisttp{l}\t$dst">;
 def ISTT_FP64m : FPI<0xDD, MRM1m, (outs), (ins i64mem:$dst), "fisttp{ll}\t$dst">;
+}
 
 // FP Stack manipulation instructions.
 def LD_Frr   : FPI<0xC0, AddRegFrm, (outs), (ins RST:$op), "fld\t$op">, D9;
@@ -531,6 +541,8 @@
 def FNSTCW16m : I<0xD9, MRM7m,                   // [mem16] = X87 control world
                   (outs), (ins i16mem:$dst), "fnstcw\t$dst",
                   [(X86fp_cwd_get16 addr:$dst)]>;
+                  
+let mayLoad = 1 in
 def FLDCW16m  : I<0xD9, MRM5m,                   // X87 control world = [mem16]
                   (outs), (ins i16mem:$dst), "fldcw\t$dst", []>;
 

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Jan 10 01:59:24 2008
@@ -92,7 +92,7 @@
                          SDNPMayLoad]>;
 
 def X86rdtsc   : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
-                        [SDNPHasChain, SDNPOutFlag]>;
+                        [SDNPHasChain, SDNPOutFlag, SDNPSideEffect]>;
 
 def X86Wrapper    : SDNode<"X86ISD::Wrapper",     SDTX86Wrapper>;
 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP",  SDTX86Wrapper>;
@@ -266,6 +266,7 @@
 def IMPLICIT_USE     : I<0, Pseudo, (outs), (ins variable_ops),
                          "#IMPLICIT_USE", []>;
 let isImplicitDef = 1 in {
+let neverHasSideEffects = 1 in
 def IMPLICIT_DEF     : I<0, Pseudo, (outs variable_ops), (ins),
                           "#IMPLICIT_DEF", []>;
 def IMPLICIT_DEF_GR8  : I<0, Pseudo, (outs GR8:$dst), (ins),
@@ -280,13 +281,13 @@
 }
 
 // Nop
-def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
+let neverHasSideEffects = 1 in
+  def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
 
 // PIC base
-let neverHasSideEffects = 1, isNotDuplicable = 1 in {
-def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins piclabel:$label),
-                    "call\t$label\n\tpop{l}\t$reg", []>;
-}
+let neverHasSideEffects = 1, isNotDuplicable = 1 in
+  def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins piclabel:$label),
+                      "call\t$label\n\tpop{l}\t$reg", []>;
 
 //===----------------------------------------------------------------------===//
 //  Control Flow Instructions...
@@ -399,19 +400,21 @@
 //===----------------------------------------------------------------------===//
 //  Miscellaneous Instructions...
 //
-let Defs = [EBP, ESP], Uses = [EBP, ESP] in
+let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, neverHasSideEffects=1 in
 def LEAVE    : I<0xC9, RawFrm,
                  (outs), (ins), "leave", []>;
 
-let Defs = [ESP], Uses = [ESP] in {
+let Defs = [ESP], Uses = [ESP], neverHasSideEffects=1 in {
+let mayLoad = 1 in
 def POP32r   : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>;
 
+let mayStore = 1 in
 def PUSH32r  : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>;
 }
 
-let Defs = [ESP, EFLAGS], Uses = [ESP] in
+let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, neverHasSideEffects=1 in
 def POPFD    : I<0x9D, RawFrm, (outs), (ins), "popf", []>;
-let Defs = [ESP], Uses = [ESP, EFLAGS] in
+let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, neverHasSideEffects=1 in
 def PUSHFD   : I<0x9C, RawFrm, (outs), (ins), "pushf", []>;
 
 let isTwoAddress = 1 in                               // GR32 = bswap GR32
@@ -483,6 +486,7 @@
                   (implicit EFLAGS)]>, TB;
 } // Defs = [EFLAGS]
 
+let neverHasSideEffects = 1 in
 def LEA16r   : I<0x8D, MRMSrcMem,
                  (outs GR16:$dst), (ins i32mem:$src),
                  "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize;
@@ -560,12 +564,14 @@
 //===----------------------------------------------------------------------===//
 //  Move Instructions...
 //
+let neverHasSideEffects = 1 in {
 def MOV8rr  : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
                 "mov{b}\t{$src, $dst|$dst, $src}", []>;
 def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
                 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
                 "mov{l}\t{$src, $dst|$dst, $src}", []>;
+}
 let isReMaterializable = 1 in {
 def MOV8ri  : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
                    "mov{b}\t{$src, $dst|$dst, $src}",
@@ -633,13 +639,16 @@
                // This probably ought to be moved to a def : Pat<> if the
                // syntax can be accepted.
                [(set AL, (mul AL, (loadi8 addr:$src)))]>;   // AL,AH = AL*[mem8]
+let mayLoad = 1, neverHasSideEffects = 1 in {
 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
 def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
                "mul{w}\t$src", []>, OpSize; // AX,DX = AX*[mem16]
 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
 def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
               "mul{l}\t$src", []>;          // EAX,EDX = EAX*[mem32]
+}
 
+let neverHasSideEffects = 1 in {
 let Defs = [AL,AH,EFLAGS], Uses = [AL] in
 def IMUL8r  : I<0xF6, MRM5r, (outs),  (ins GR8:$src), "imul{b}\t$src", []>;
               // AL,AH = AL*GR8
@@ -649,6 +658,7 @@
 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
 def IMUL32r : I<0xF7, MRM5r, (outs),  (ins GR32:$src), "imul{l}\t$src", []>;
               // EAX,EDX = EAX*GR32
+let mayLoad = 1 in {
 let Defs = [AL,AH,EFLAGS], Uses = [AL] in
 def IMUL8m  : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
                 "imul{b}\t$src", []>;    // AL,AH = AL*[mem8]
@@ -658,6 +668,7 @@
 let Defs = [EAX,EDX], Uses = [EAX] in
 def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
                 "imul{l}\t$src", []>;  // EAX,EDX = EAX*[mem32]
+}
 
 // unsigned division/remainder
 let Defs = [AX,EFLAGS], Uses = [AL,AH] in
@@ -669,6 +680,7 @@
 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
 def DIV32r : I<0xF7, MRM6r, (outs),  (ins GR32:$src),         // EDX:EAX/r32 = EAX,EDX
                "div{l}\t$src", []>;
+let mayLoad = 1 in {
 let Defs = [AX,EFLAGS], Uses = [AL,AH] in
 def DIV8m  : I<0xF6, MRM6m, (outs), (ins i8mem:$src),       // AX/[mem8] = AL,AH
                "div{b}\t$src", []>;
@@ -678,6 +690,7 @@
 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
 def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),      // EDX:EAX/[mem32] = EAX,EDX
                "div{l}\t$src", []>;
+}
 
 // Signed division/remainder.
 let Defs = [AX,EFLAGS], Uses = [AL,AH] in
@@ -689,6 +702,7 @@
 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
 def IDIV32r: I<0xF7, MRM7r, (outs),  (ins GR32:$src),         // EDX:EAX/r32 = EAX,EDX
                "idiv{l}\t$src", []>;
+let mayLoad = 1, mayLoad = 1 in {
 let Defs = [AX,EFLAGS], Uses = [AL,AH] in
 def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src),      // AX/[mem8] = AL,AH
                "idiv{b}\t$src", []>;
@@ -698,10 +712,11 @@
 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
 def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),     // EDX:EAX/[mem32] = EAX,EDX
                "idiv{l}\t$src", []>;
-
+}
+} // neverHasSideEffects
 
 //===----------------------------------------------------------------------===//
-//  Two address Instructions...
+//  Two address Instructions.
 //
 let isTwoAddress = 1 in {
 
@@ -2161,9 +2176,9 @@
 
 
 // Condition code ops, incl. set if equal/not equal/...
-let Defs = [EFLAGS], Uses = [AH] in
+let Defs = [EFLAGS], Uses = [AH], neverHasSideEffects = 1 in
 def SAHF     : I<0x9E, RawFrm, (outs),  (ins), "sahf", []>;  // flags = AH
-let Defs = [AH], Uses = [EFLAGS] in
+let Defs = [AH], Uses = [EFLAGS], neverHasSideEffects = 1 in
 def LAHF     : I<0x9F, RawFrm, (outs),  (ins), "lahf", []>;  // AH = flags
 
 let Uses = [EFLAGS] in {
@@ -2445,20 +2460,21 @@
                    "movz{wl|x}\t{$src, $dst|$dst, $src}",
                    [(set GR32:$dst, (zextloadi32i16 addr:$src))]>, TB;
 
-let Defs = [AX], Uses = [AL] in
-def CBW : I<0x98, RawFrm, (outs), (ins),
-            "{cbtw|cbw}", []>, OpSize;   // AX = signext(AL)
-let Defs = [EAX], Uses = [AX] in
-def CWDE : I<0x98, RawFrm, (outs), (ins),
-            "{cwtl|cwde}", []>;   // EAX = signext(AX)
-
-let Defs = [AX,DX], Uses = [AX] in
-def CWD : I<0x99, RawFrm, (outs), (ins),
-            "{cwtd|cwd}", []>, OpSize; // DX:AX = signext(AX)
-let Defs = [EAX,EDX], Uses = [EAX] in
-def CDQ : I<0x99, RawFrm, (outs), (ins),
-            "{cltd|cdq}", []>; // EDX:EAX = signext(EAX)
-          
+let neverHasSideEffects = 1 in {
+  let Defs = [AX], Uses = [AL] in
+  def CBW : I<0x98, RawFrm, (outs), (ins),
+              "{cbtw|cbw}", []>, OpSize;   // AX = signext(AL)
+  let Defs = [EAX], Uses = [AX] in
+  def CWDE : I<0x98, RawFrm, (outs), (ins),
+              "{cwtl|cwde}", []>;   // EAX = signext(AX)
+
+  let Defs = [AX,DX], Uses = [AX] in
+  def CWD : I<0x99, RawFrm, (outs), (ins),
+              "{cwtd|cwd}", []>, OpSize; // DX:AX = signext(AX)
+  let Defs = [EAX,EDX], Uses = [EAX] in
+  def CDQ : I<0x99, RawFrm, (outs), (ins),
+              "{cltd|cdq}", []>; // EDX:EAX = signext(EAX)
+}
 
 //===----------------------------------------------------------------------===//
 // Alias Instructions
@@ -2480,25 +2496,30 @@
 
 // Basic operations on GR16 / GR32 subclasses GR16_ and GR32_ which contains only
 // those registers that have GR8 sub-registers (i.e. AX - DX, EAX - EDX).
+let neverHasSideEffects = 1 in {
 def MOV16to16_ : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16:$src),
                 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32to32_ : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32:$src),
                 "mov{l}\t{$src, $dst|$dst, $src}", []>;
-
+                
 def MOV16_rr : I<0x89, MRMDestReg, (outs GR16_:$dst), (ins GR16_:$src),
                 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32_rr : I<0x89, MRMDestReg, (outs GR32_:$dst), (ins GR32_:$src),
                 "mov{l}\t{$src, $dst|$dst, $src}", []>;
-let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
+} // neverHasSideEffects
+
+let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
 def MOV16_rm : I<0x8B, MRMSrcMem, (outs GR16_:$dst), (ins i16mem:$src),
                 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32_rm : I<0x8B, MRMSrcMem, (outs GR32_:$dst), (ins i32mem:$src),
                 "mov{l}\t{$src, $dst|$dst, $src}", []>;
 }
+let mayStore = 1, neverHasSideEffects = 1 in {
 def MOV16_mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16_:$src),
                 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize;
 def MOV32_mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32_:$src),
                 "mov{l}\t{$src, $dst|$dst, $src}", []>;
+}
 
 //===----------------------------------------------------------------------===//
 // Thread Local Storage Instructions

Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrMMX.td?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrMMX.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrMMX.td Thu Jan 10 01:59:24 2008
@@ -156,17 +156,21 @@
 //===----------------------------------------------------------------------===//
 
 // Data Transfer Instructions
+let neverHasSideEffects = 1 in
 def MMX_MOVD64rr : MMXI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR32:$src),
                         "movd\t{$src, $dst|$dst, $src}", []>;
-let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
+let isSimpleLoad = 1, mayLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
 def MMX_MOVD64rm : MMXI<0x6E, MRMSrcMem, (outs VR64:$dst), (ins i32mem:$src),
                         "movd\t{$src, $dst|$dst, $src}", []>;
+let mayStore = 1 in 
 def MMX_MOVD64mr : MMXI<0x7E, MRMDestMem, (outs), (ins i32mem:$dst, VR64:$src),
                         "movd\t{$src, $dst|$dst, $src}", []>;
 
+let neverHasSideEffects = 1 in
 def MMX_MOVD64to64rr : MMXRI<0x6E, MRMSrcReg, (outs VR64:$dst), (ins GR64:$src),
                              "movd\t{$src, $dst|$dst, $src}", []>;
 
+let neverHasSideEffects = 1 in
 def MMX_MOVQ64rr : MMXI<0x6F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src),
                         "movq\t{$src, $dst|$dst, $src}", []>;
 let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
@@ -417,35 +421,44 @@
                                     MMX_PSHUFW_shuffle_mask:$src2)))]>;
 
 // -- Conversion Instructions
+let neverHasSideEffects = 1 in {
 def MMX_CVTPD2PIrr  : MMX2I<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
                             "cvtpd2pi\t{$src, $dst|$dst, $src}", []>;
+let mayLoad = 1 in
 def MMX_CVTPD2PIrm  : MMX2I<0x2D, MRMSrcMem, (outs VR64:$dst), (ins f128mem:$src),
                             "cvtpd2pi\t{$src, $dst|$dst, $src}", []>;
 
 def MMX_CVTPI2PDrr  : MMX2I<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR64:$src),
                             "cvtpi2pd\t{$src, $dst|$dst, $src}", []>;
+let mayLoad = 1 in
 def MMX_CVTPI2PDrm  : MMX2I<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
                             "cvtpi2pd\t{$src, $dst|$dst, $src}", []>;
 
 def MMX_CVTPI2PSrr  : MMXI<0x2A, MRMSrcReg, (outs VR128:$dst), (ins VR64:$src),
                            "cvtpi2ps\t{$src, $dst|$dst, $src}", []>;
+let mayLoad = 1 in
 def MMX_CVTPI2PSrm  : MMXI<0x2A, MRMSrcMem, (outs VR128:$dst), (ins i64mem:$src),
                            "cvtpi2ps\t{$src, $dst|$dst, $src}", []>;
 
 def MMX_CVTPS2PIrr  : MMXI<0x2D, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
                            "cvtps2pi\t{$src, $dst|$dst, $src}", []>;
+let mayLoad = 1 in
 def MMX_CVTPS2PIrm  : MMXI<0x2D, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src),
                            "cvtps2pi\t{$src, $dst|$dst, $src}", []>;
 
 def MMX_CVTTPD2PIrr : MMX2I<0x2C, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
                             "cvttpd2pi\t{$src, $dst|$dst, $src}", []>;
+let mayLoad = 1 in
 def MMX_CVTTPD2PIrm : MMX2I<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f128mem:$src),
                             "cvttpd2pi\t{$src, $dst|$dst, $src}", []>;
 
 def MMX_CVTTPS2PIrr : MMXI<0x2C, MRMSrcReg, (outs VR64:$dst), (ins VR128:$src),
                            "cvttps2pi\t{$src, $dst|$dst, $src}", []>;
+let mayLoad = 1 in
 def MMX_CVTTPS2PIrm : MMXI<0x2C, MRMSrcMem, (outs VR64:$dst), (ins f64mem:$src),
                            "cvttps2pi\t{$src, $dst|$dst, $src}", []>;
+} // end neverHasSideEffects
+
 
 // Extract / Insert
 def MMX_X86pextrw : SDNode<"X86ISD::PEXTRW", SDTypeProfile<1, 2, []>, []>;

Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Thu Jan 10 01:59:24 2008
@@ -42,7 +42,7 @@
 // SSE 'Special' Instructions
 //===----------------------------------------------------------------------===//
 
-let isImplicitDef = 1 in
+let isImplicitDef = 1 in {
 def IMPLICIT_DEF_VR128 : I<0, Pseudo, (outs VR128:$dst), (ins),
                            "#IMPLICIT_DEF $dst",
                            [(set VR128:$dst, (v4f32 (undef)))]>,
@@ -53,6 +53,7 @@
 def IMPLICIT_DEF_FR64  : I<0, Pseudo, (outs FR64:$dst), (ins),
                            "#IMPLICIT_DEF $dst",
                            [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>;
+}
 
 //===----------------------------------------------------------------------===//
 // SSE Complex Patterns
@@ -62,9 +63,9 @@
 // the top elements.  These are used for the SSE 'ss' and 'sd' instruction
 // forms.
 def sse_load_f32 : ComplexPattern<v4f32, 4, "SelectScalarSSELoad", [],
-                                  [SDNPHasChain]>;
+                                  [SDNPHasChain, SDNPMayLoad]>;
 def sse_load_f64 : ComplexPattern<v2f64, 4, "SelectScalarSSELoad", [],
-                                  [SDNPHasChain]>;
+                                  [SDNPHasChain, SDNPMayLoad]>;
 
 def ssmem : Operand<v4f32> {
   let PrintMethod = "printf32mem";
@@ -452,6 +453,7 @@
 
 // Alias instruction to do FR32 reg-to-reg copy using movaps. Upper bits are
 // disregarded.
+let neverHasSideEffects = 1 in 
 def FsMOVAPSrr : PSI<0x28, MRMSrcReg, (outs FR32:$dst), (ins FR32:$src),
                      "movaps\t{$src, $dst|$dst, $src}", []>;
 
@@ -488,14 +490,17 @@
                     "xorps\t{$src2, $dst|$dst, $src2}",
                     [(set FR32:$dst, (X86fxor FR32:$src1,
                                       (memopfsf32 addr:$src2)))]>;
-
+let neverHasSideEffects = 1 in {
 def FsANDNPSrr : PSI<0x55, MRMSrcReg,
                      (outs FR32:$dst), (ins FR32:$src1, FR32:$src2),
                      "andnps\t{$src2, $dst|$dst, $src2}", []>;
+                     
+let mayLoad = 1 in
 def FsANDNPSrm : PSI<0x55, MRMSrcMem,
                      (outs FR32:$dst), (ins FR32:$src1, f128mem:$src2),
                      "andnps\t{$src2, $dst|$dst, $src2}", []>;
 }
+}
 
 /// basic_sse1_fp_binop_rm - SSE1 binops come in both scalar and vector forms.
 ///
@@ -632,6 +637,7 @@
 // SSE packed FP Instructions
 
 // Move Instructions
+let neverHasSideEffects = 1 in 
 def MOVAPSrr : PSI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
                    "movaps\t{$src, $dst|$dst, $src}", []>;
 let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
@@ -1148,6 +1154,7 @@
 
 // Alias instruction to do FR64 reg-to-reg copy using movapd. Upper bits are
 // disregarded.
+let neverHasSideEffects = 1 in
 def FsMOVAPDrr : PDI<0x28, MRMSrcReg, (outs FR64:$dst), (ins FR64:$src),
                      "movapd\t{$src, $dst|$dst, $src}", []>;
 
@@ -1185,13 +1192,16 @@
                     [(set FR64:$dst, (X86fxor FR64:$src1,
                                       (memopfsf64 addr:$src2)))]>;
 
+let neverHasSideEffects = 1 in {
 def FsANDNPDrr : PDI<0x55, MRMSrcReg,
                      (outs FR64:$dst), (ins FR64:$src1, FR64:$src2),
                      "andnpd\t{$src2, $dst|$dst, $src2}", []>;
+let mayLoad = 1 in
 def FsANDNPDrm : PDI<0x55, MRMSrcMem,
                      (outs FR64:$dst), (ins FR64:$src1, f128mem:$src2),
                      "andnpd\t{$src2, $dst|$dst, $src2}", []>;
 }
+}
 
 /// basic_sse2_fp_binop_rm - SSE2 binops come in both scalar and vector forms.
 ///
@@ -1328,6 +1338,7 @@
 // SSE packed FP Instructions
 
 // Move Instructions
+let neverHasSideEffects = 1 in
 def MOVAPDrr : PDI<0x28, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src),
                    "movapd\t{$src, $dst|$dst, $src}", []>;
 let isSimpleLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
@@ -2117,7 +2128,6 @@
 def MFENCE : I<0xAE, MRM6m, (outs), (ins),
                "mfence", [(int_x86_sse2_mfence)]>, TB, Requires<[HasSSE2]>;
 
-
 // Alias instructions that map zero vector to pxor / xorp* for sse.
 let isReMaterializable = 1 in
   def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins),

Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Thu Jan 10 01:59:24 2008
@@ -97,14 +97,14 @@
   usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
   hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
   isNotDuplicable = R->getValueAsBit("isNotDuplicable");
+  hasSideEffects = R->getValueAsBit("hasSideEffects");
   mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects");
   neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
   hasOptionalDef = false;
   isVariadic = false;
 
-  if (mayHaveSideEffects && neverHasSideEffects)
-    throw R->getName() +
-      ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!";
+  if (mayHaveSideEffects + neverHasSideEffects + hasSideEffects > 1)
+    throw R->getName() + ": multiple conflicting side-effect flags set!";
 
   DagInit *DI;
   try {

Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.h?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.h Thu Jan 10 01:59:24 2008
@@ -103,8 +103,7 @@
     bool hasCtrlDep;
     bool isNotDuplicable;
     bool hasOptionalDef;
-    bool mayHaveSideEffects;
-    bool neverHasSideEffects;
+    bool hasSideEffects, mayHaveSideEffects, neverHasSideEffects;
     
     /// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
     /// where $foo is a whole operand and $foo.bar refers to a suboperand.

Modified: llvm/trunk/utils/TableGen/CodeGenTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenTarget.cpp?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenTarget.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp Thu Jan 10 01:59:24 2008
@@ -340,6 +340,12 @@
       Properties |= 1 << SDNPHasChain;
     } else if (PropList[i]->getName() == "SDNPOptInFlag") {
       Properties |= 1 << SDNPOptInFlag;
+    } else if (PropList[i]->getName() == "SDNPMayStore") {
+      Properties |= 1 << SDNPMayStore;
+    } else if (PropList[i]->getName() == "SDNPMayLoad") {
+      Properties |= 1 << SDNPMayLoad;
+    } else if (PropList[i]->getName() == "SDNPSideEffect") {
+      Properties |= 1 << SDNPSideEffect;
     } else {
       cerr << "Unsupported SD Node property '" << PropList[i]->getName()
            << "' on ComplexPattern '" << R->getName() << "'!\n";

Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=45829&r1=45828&r2=45829&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Thu Jan 10 01:59:24 2008
@@ -152,22 +152,36 @@
     : CDP(cdp), mayStore(maystore), mayLoad(mayload), HasSideEffects(hse){
   }
   
-  void Analyze(Record *InstRecord) {
+  /// Analyze - Analyze the specified instruction, returning true if the
+  /// instruction had a pattern.
+  bool Analyze(Record *InstRecord) {
     const TreePattern *Pattern = CDP.getInstruction(InstRecord).getPattern();
     if (Pattern == 0) {
       HasSideEffects = 1;
-      return;  // No pattern.
+      return false;  // No pattern.
     }
     
     // FIXME: Assume only the first tree is the pattern. The others are clobber
     // nodes.
     AnalyzeNode(Pattern->getTree(0));
+    return true;
   }
   
 private:
   void AnalyzeNode(const TreePatternNode *N) {
-    if (N->isLeaf())
+    if (N->isLeaf()) {
+      if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
+        Record *LeafRec = DI->getDef();
+        // Handle ComplexPattern leaves.
+        if (LeafRec->isSubClassOf("ComplexPattern")) {
+          const ComplexPattern &CP = CDP.getComplexPattern(LeafRec);
+          if (CP.hasProperty(SDNPMayStore)) mayStore = true;
+          if (CP.hasProperty(SDNPMayLoad)) mayLoad = true;
+          if (CP.hasProperty(SDNPSideEffect)) HasSideEffects = true;
+        }
+      }
       return;
+    }
 
     // Analyze children.
     for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
@@ -180,17 +194,10 @@
     // Get information about the SDNode for the operator.
     const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
     
-    // If node writes to memory, it obviously stores to memory.
-    if (OpInfo.hasProperty(SDNPMayStore))
-      mayStore = true;
-    
-    // If it reads memory, remember this.
-    if (OpInfo.hasProperty(SDNPMayLoad))
-      mayLoad = true;
-
-    // If it reads memory, remember this.
-    if (OpInfo.hasProperty(SDNPSideEffect))
-      HasSideEffects = true;
+    // Notice properties of the node.
+    if (OpInfo.hasProperty(SDNPMayStore)) mayStore = true;
+    if (OpInfo.hasProperty(SDNPMayLoad)) mayLoad = true;
+    if (OpInfo.hasProperty(SDNPSideEffect)) HasSideEffects = true;
     
     if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
       // If this is an intrinsic, analyze it.
@@ -213,7 +220,8 @@
                                         bool &HasSideEffects) {
   MayStore = MayLoad = HasSideEffects = false;
   
-  InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
+  bool HadPattern =
+    InstAnalyzer(CDP, MayStore, MayLoad, HasSideEffects).Analyze(Inst.TheDef);
 
   // InstAnalyzer only correctly analyzes mayStore/mayLoad so far.
   if (Inst.mayStore) {  // If the .td file explicitly sets mayStore, use it.
@@ -239,15 +247,18 @@
   }
   
   if (Inst.neverHasSideEffects) {
-    // If we already decided that this instruction has no side effects, then the
-    // .td file entry is redundant.
-    if (!HasSideEffects)
-      fprintf(stderr, 
-              "Warning: neverHasSideEffects flag explicitly set on instruction"
-              " '%s' but flag already inferred from pattern.\n", 
-              Inst.TheDef->getName().c_str());
+    if (HadPattern)
+      fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' "
+              "which already has a pattern\n", Inst.TheDef->getName().c_str());
     HasSideEffects = false;
   }
+  
+  if (Inst.hasSideEffects) {
+    if (HasSideEffects)
+      fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' "
+              "which already inferred this.\n", Inst.TheDef->getName().c_str());
+    HasSideEffects = true;
+  }
 }
 
 





More information about the llvm-commits mailing list