<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 23, 2015 at 5:23 AM, Michael Kuperstein <span dir="ltr"><<a href="mailto:michael.m.kuperstein@intel.com" target="_blank">michael.m.kuperstein@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: mkuper<br>
Date: Thu Jul 23 07:23:45 2015<br>
New Revision: 243010<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D243010-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=m6jqT7zyumOjyrv_sdS3mw0Mtv6kEcTX3w2y1vx_Y4g&s=u7U-xd_UovJ1hm5fQ4QAw5OqEcvhMccOuN8v9IhMRqs&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=243010&view=rev</a><br>
Log:<br>
[X86] Allow load folding into PUSH instructions<br>
<br>
Adds pushes to the folding tables.<br>
This also required a fix to the TD definition, since the memory forms of<br>
the push instructions did not have the right mayLoad/mayStore flags.<br>
<br>
Differential Revision: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D11340&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=m6jqT7zyumOjyrv_sdS3mw0Mtv6kEcTX3w2y1vx_Y4g&s=w3noeOj5DPGgOl_fGat50xkDroLaM9_gy9_I_wnIY6k&e=" rel="noreferrer" target="_blank">http://reviews.llvm.org/D11340</a><br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/X86/fold-push.ll<br>
Modified:<br>
    llvm/trunk/lib/Target/X86/X86.td<br>
    llvm/trunk/lib/Target/X86/X86InstrInfo.cpp<br>
    llvm/trunk/lib/Target/X86/X86InstrInfo.td<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86.td<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_X86_X86.td-3Frev-3D243010-26r1-3D243009-26r2-3D243010-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=m6jqT7zyumOjyrv_sdS3mw0Mtv6kEcTX3w2y1vx_Y4g&s=Ms9gA7BkeS-uj1s6CJd7Bj4pC_I_FfBIVmHFnhwYaP8&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=243010&r1=243009&r2=243010&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86.td (original)<br>
+++ llvm/trunk/lib/Target/X86/X86.td Thu Jul 23 07:23:45 2015<br>
@@ -181,6 +181,11 @@ def FeatureSlowDivide64 : SubtargetFeatu<br>
 def FeaturePadShortFunctions : SubtargetFeature<"pad-short-functions",<br>
                                      "PadShortFunctions", "true",<br>
                                      "Pad short functions">;<br>
+// TODO: This feature ought to be renamed.<br>
+// What it really refers to are CPUs where instruction that cause MSROM<br>
+// lookups are expensive, so alternative sequences should be preferred.<br></blockquote><div><br></div><div>What is "MSROM" in this context? Do you just mean that the instruction is microcoded?</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+// The best examples of this are the memory forms of CALL and PUSH<br>
+// instructions, which should be avoided in favor of a MOV + register CALL/PUSH.<br>
 def FeatureCallRegIndirect : SubtargetFeature<"call-reg-indirect",<br>
                                      "CallRegIndirect", "true",<br>
                                      "Call register indirect">;<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_X86_X86InstrInfo.cpp-3Frev-3D243010-26r1-3D243009-26r2-3D243010-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=m6jqT7zyumOjyrv_sdS3mw0Mtv6kEcTX3w2y1vx_Y4g&s=XuVc80Hi62Sp1Wuf-OqbAh1ei2lufGyR4iiWxTtYimg&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=243010&r1=243009&r2=243010&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Thu Jul 23 07:23:45 2015<br>
@@ -332,6 +332,9 @@ X86InstrInfo::X86InstrInfo(X86Subtarget<br>
     { X86::MUL8r,       X86::MUL8m,         TB_FOLDED_LOAD },<br>
     { X86::PEXTRDrr,    X86::PEXTRDmr,      TB_FOLDED_STORE },<br>
     { X86::PEXTRQrr,    X86::PEXTRQmr,      TB_FOLDED_STORE },<br>
+    { X86::PUSH16r,     X86::PUSH16rmm,     TB_FOLDED_LOAD },<br>
+    { X86::PUSH32r,     X86::PUSH32rmm,     TB_FOLDED_LOAD },<br>
+    { X86::PUSH64r,     X86::PUSH64rmm,     TB_FOLDED_LOAD },<br>
     { X86::SETAEr,      X86::SETAEm,        TB_FOLDED_STORE },<br>
     { X86::SETAr,       X86::SETAm,         TB_FOLDED_STORE },<br>
     { X86::SETBEr,      X86::SETBEm,        TB_FOLDED_STORE },<br>
@@ -4878,10 +4881,14 @@ MachineInstr *X86InstrInfo::foldMemoryOp<br>
   bool isCallRegIndirect = Subtarget.callRegIndirect();<br>
   bool isTwoAddrFold = false;<br>
<br>
-  // For CPUs that favor the register form of a call,<br>
-  // do not fold loads into calls.<br>
-  if (isCallRegIndirect &&<br>
-    (MI->getOpcode() == X86::CALL32r || MI->getOpcode() == X86::CALL64r))<br>
+  // For CPUs that favor the register form of a call or push,<br>
+  // do not fold loads into calls or pushes, unless optimizing for size<br>
+  // aggressively.<br>
+  if (isCallRegIndirect &&<br>
+      !MF.getFunction()->hasFnAttribute(Attribute::MinSize) &&<br>
+      (MI->getOpcode() == X86::CALL32r || MI->getOpcode() == X86::CALL64r ||<br>
+       MI->getOpcode() == X86::PUSH16r || MI->getOpcode() == X86::PUSH32r ||<br>
+       MI->getOpcode() == X86::PUSH64r))<br>
     return nullptr;<br>
<br>
   unsigned NumOps = MI->getDesc().getNumOperands();<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_X86_X86InstrInfo.td-3Frev-3D243010-26r1-3D243009-26r2-3D243010-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=m6jqT7zyumOjyrv_sdS3mw0Mtv6kEcTX3w2y1vx_Y4g&s=DpQ0YIz5QMzyHedB7RnZnJ5b6SXpLXNfr5b9Xqtnox0&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=243010&r1=243009&r2=243010&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Thu Jul 23 07:23:45 2015<br>
@@ -1022,12 +1022,8 @@ def PUSH32r  : I<0x50, AddRegFrm, (outs)<br>
                  IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;<br>
 def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[],<br>
                  IIC_PUSH_REG>, OpSize16;<br>
-def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],<br>
-                 IIC_PUSH_MEM>, OpSize16;<br>
 def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[],<br>
                  IIC_PUSH_REG>, OpSize32, Requires<[Not64BitMode]>;<br>
-def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],<br>
-                 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;<br>
<br>
 def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),<br>
                    "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize16;<br>
@@ -1041,6 +1037,14 @@ def PUSHi32  : Ii32<0x68, RawFrm, (outs)<br>
                    "push{l}\t$imm", [], IIC_PUSH_IMM>, OpSize32,<br>
                    Requires<[Not64BitMode]>;<br>
 } // mayStore, SchedRW<br>
+<br>
+let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {<br>
+def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src",[],<br>
+                 IIC_PUSH_MEM>, OpSize16;<br>
+def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src",[],<br>
+                 IIC_PUSH_MEM>, OpSize32, Requires<[Not64BitMode]>;<br>
+} // mayLoad, mayStore, SchedRW<br>
+<br>
 }<br>
<br>
 let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, hasSideEffects=0,<br>
@@ -1073,9 +1077,11 @@ def PUSH64r  : I<0x50, AddRegFrm, (outs)<br>
                  IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;<br>
 def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", [],<br>
                  IIC_PUSH_REG>, OpSize32, Requires<[In64BitMode]>;<br>
+} // mayStore, SchedRW<br>
+let mayLoad = 1, mayStore = 1, SchedRW = [WriteRMW] in {<br>
 def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", [],<br>
                  IIC_PUSH_MEM>, OpSize32, Requires<[In64BitMode]>;<br>
-} // mayStore, SchedRW<br>
+} // mayLoad, mayStore, SchedRW<br>
 }<br>
<br>
 let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/fold-push.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_X86_fold-2Dpush.ll-3Frev-3D243010-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=m6jqT7zyumOjyrv_sdS3mw0Mtv6kEcTX3w2y1vx_Y4g&s=AeDy1G880SrHqSapCyxXE-CJTMbRPXIzz1JjErSE2F8&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-push.ll?rev=243010&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/fold-push.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/fold-push.ll Thu Jul 23 07:23:45 2015<br>
@@ -0,0 +1,40 @@<br>
+; RUN: llc < %s -mtriple=i686-windows | FileCheck %s -check-prefix=CHECK -check-prefix=NORMAL<br>
+; RUN: llc < %s -mtriple=i686-windows -mattr=call-reg-indirect | FileCheck %s -check-prefix=CHECK -check-prefix=SLM<br>
+<br>
+declare void @foo(i32 %r)<br>
+<br>
+define void @test(i32 %a, i32 %b) optsize {<br>
+; CHECK-LABEL: test:<br>
+; CHECK: movl [[EAX:%e..]], (%esp)<br>
+; CHECK-NEXT: pushl [[EAX]]<br>
+; CHECK-NEXT: calll<br>
+; CHECK-NEXT: addl $4, %esp<br>
+; CHECK: nop<br>
+; NORMAL: pushl (%esp)<br>
+; SLM: movl (%esp), [[RELOAD:%e..]]<br>
+; SLM-NEXT: pushl [[RELOAD]]<br>
+; CHECK: calll<br>
+; CHECK-NEXT: addl $4, %esp<br>
+  %c = add i32 %a, %b<br>
+  call void @foo(i32 %c)<br>
+  call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di}"()<br>
+  call void @foo(i32 %c)<br>
+  ret void<br>
+}<br>
+<br>
+define void @test_min(i32 %a, i32 %b) minsize {<br>
+; CHECK-LABEL: test_min:<br>
+; CHECK: movl [[EAX:%e..]], (%esp)<br>
+; CHECK-NEXT: pushl [[EAX]]<br>
+; CHECK-NEXT: calll<br>
+; CHECK-NEXT: addl $4, %esp<br>
+; CHECK: nop<br>
+; CHECK: pushl (%esp)<br>
+; CHECK: calll<br>
+; CHECK-NEXT: addl $4, %esp<br>
+  %c = add i32 %a, %b<br>
+  call void @foo(i32 %c)<br>
+  call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di}"()<br>
+  call void @foo(i32 %c)<br>
+  ret void<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>