[LLVMdev] RFC: Tail call optimization X86

Evan Cheng evan.cheng at apple.com
Mon Sep 24 00:18:46 PDT 2007


Hi Arnold,

This is a very good first step! Thanks! Comments below.

Evan

Index: test/CodeGen/X86/constant-pool-remat-0.ll
===================================================================
--- test/CodeGen/X86/constant-pool-remat-0.ll	(revision 42247)
+++ test/CodeGen/X86/constant-pool-remat-0.ll	(working copy)
@@ -1,8 +1,10 @@
; RUN: llvm-as < %s | llc -march=x86-64 | grep LCPI | count 3
; RUN: llvm-as < %s | llc -march=x86-64 -stats -info-output-file - |  
grep asm-printer | grep 6
; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep LCPI | count 3
-; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -stats -info- 
output-file - | grep asm-printer | grep 8
-
+; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -stats -info- 
output-file - | grep asm-printer | grep 9
+; change preceeding line form ... | grep 8 to ..| grep 9 since
+; with new fastcc has std call semantics causing a stack adjustment
+; after the function call

Not sure if I understand this. Can you illustrate with an example?

Index: include/llvm/Target/TargetLowering.h
===================================================================
--- include/llvm/Target/TargetLowering.h	(revision 42247)
+++ include/llvm/Target/TargetLowering.h	(working copy)
@@ -851,8 +851,18 @@
    virtual std::pair<SDOperand, SDOperand>
    LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetTyIsSigned,
                bool isVarArg, unsigned CallingConv, bool isTailCall,
-              SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
+              bool isNextInstRet, SDOperand Callee, ArgListTy &Args,
+              SelectionDAG &DAG);
+  // IsEligibleForTailCallElimination - Check whether the call is  
eligible for
+  // tailcall elimination
+  virtual bool IsEligibleForTailCallElimination(SelectionDAG& DAG,
+                                                bool IsNextInstRet,
+                                                SDOperand Callee,
+                                                unsigned CalleeCC)  
const {
+    return false;
+  }
+

I am not too keen on "isNextInstRet". We should never use instruction  
ordering before scheduling to determine whether it's possible to  
perform an optimization. IsEligibleForTailCallElimination() should  
determine the feasibility on its own, no?


+// check whether the instruction following the tailcall is a return  
instruction
+// and whether its return type is void or if it uses the value  
defined by the
+// tail call
+bool IsNextInstructionReturn(Instruction &I) {
+  bool IsNextInstRet = false;
+  BasicBlock *BB = I.getParent();
+  BasicBlock::iterator BI = &I;
+  assert(BI != BB->end() && "Woohooa");
+  ++BI;
+  if (BI != BB->end()) {
+    ReturnInst *RI = dyn_cast<ReturnInst>(BI);
+    if (RI) {
+      if (RI->getReturnValue()==0 ||
+          std::find(RI->op_begin(), RI->op_end(),
+                    (Value*)&I) != RI->op_end()) {
+        IsNextInstRet=true;
+      }
+    }
+  }
+  return IsNextInstRet;
+}
+

Some stylistic nitpicks. Please write the comments as:
/// IsNextInstructionReturn - Check whether..

+  assert(BI != BB->end() && "Woohooa");
Better assertion messages please. :-)

Why not write it like this:

+bool IsNextInstructionReturn(Instruction &I) {
+  BasicBlock *BB = I.getParent();
+  BasicBlock::iterator BI = &I;
+  assert(BI != BB->end() && "Woohooa");
+  ++BI;
+  if (BI != BB->end()) {
+    if (ReturnInst *RI = dyn_cast<ReturnInst>(BI)) {
+      if (RI->getReturnValue()==0 ||
+          std::find(RI->op_begin(), RI->op_end(),
+                    (Value*)&I) != RI->op_end())
+        return true;
+    }
+  }
+  return false;
+}

Also, shouldn't this function be "static"?

let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
+  def TAILJMPd : IBr<0xE9, (ins i32imm:$dst), "jmp\t${dst:call}  #  
TAILCALL",
+                 []>;
+let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
+  def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*} 
$dst  # TAILCALL",
+                 []>;
+let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
    def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem:$dst),
                     "jmp\t{*}$dst  # TAIL CALL", []>;

Please fix the inconsistency: "TAILCALL" vs. "TAIL CALL".

+SDOperand GetPossiblePreceedingTailCall(SDOperand Chain) {

This should be "static"?

+
+  Chain = DAG.getNode( X86ISD::CALL,
                        NodeTys, &Ops[0], Ops.size());

Stylistic nitpick: please merge 2 lines and remove the space after '('.

-    Chain = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops, 2);
-    Flag = Chain.getValue(1);
+      Chain = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops, 2);
+      Flag = Chain.getValue(1);

What happened here?


+// Check to see whether the next instruction following the call is a  
return
+// A function is eligible if caller/callee calling conventions  
match, currently
+// only fastcc supports tail calls, and the function CALL is  
immediatly followed
+// by a RET
+bool X86TargetLowering::IsEligibleForTailCallElimination 
(SelectionDAG& DAG,
+                                                         bool  
IsNextInstRet,
+                                                         SDOperand  
Callee,
+                                                         unsigned  
CalleeCC)
+  const {

Having "const {" on a separate line looks funky. :-)

+  bool IsEligible = false;
+  //if (IsNextInstRet && false == Subtarget->is64Bit()) {

Please remove code that's commented out.

+        if(  G != 0 &&
+             (GV = G->getGlobal()) &&
+             (GV->hasHiddenVisibility() || GV->hasProtectedVisibility 
()))
+          IsEligible=true;
+        else
+        IsEligible=false;

if( G  ==> if (G  :-)

No need to set IsEligible to false since it's initialized to false.

Evan

On Sep 23, 2007, at 9:58 AM, Arnold Schwaighofer wrote:

> The patch is against revision 42247.
> <tailcall-src.patch>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list