[PATCH] Teach the inliner how to preserve musttail invariants

Chandler Carruth chandlerc at gmail.com
Tue May 6 11:43:41 PDT 2014


================
Comment at: lib/IR/Instructions.cpp:327
@@ -326,3 +326,3 @@
   setAttributes(CI.getAttributes());
-  setTailCall(CI.isTailCall());
+  setTailCallKind(CI.getTailCallKind());
   setCallingConv(CI.getCallingConv());
----------------
Please commit this separately with a separate test? Maybe a unittest?

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:483
@@ -480,1 +482,3 @@
 
+static bool isPrecededByMustTailCall(const Instruction *Inst) {
+  const Instruction *Prev = Inst->getPrevNode();
----------------
This is called in a context that needs it to not go truly linear... And it doesn't. I almost want to call it 'isImmediatelyPrecededByMustTailCall', but the bitcast thing makes that a lie. Maybe just some comments?

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:687-690
@@ +686,6 @@
+  //
+  //    f -> musttail g -> musttail h  ==>  f -> musttail g
+  //    f -> musttail g ->     tail h  ==>  f ->     tail g
+  //    f ->          g -> musttail h  ==>  f ->          g
+  //    f ->          g ->     tail h  ==>  f ->          g
+  //
----------------
I assume the after cases should have "h"? Actually, shouldn't these be "f -> g -> f" => "f -> f"?

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:692-693
@@ +691,4 @@
+  //
+  // Also, calls inlined through a 'nounwind' call site should be marked
+  // 'nounwind'.
+  bool InlinedMustTailCalls = false;
----------------
I would sink this comment to the loop body.

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:744-745
@@ +743,4 @@
+      for (ReturnInst *RI : Returns) {
+        // Don't insert lifetime.end calls after a musttail call, the allocas
+        // are trivially dead.
+        if (InlinedMustTailCalls && isPrecededByMustTailCall(RI))
----------------
Do all of the passes using lifetime markers know this?

It might be useful to separate this into its own patch with its own test case.

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:795
@@ +794,3 @@
+      // Change users of the return value of the call.  For a musttail call
+      // site, the only real user should be a return instruction with an
+      // optional bitcast.  Avoid chains of bitcasts.
----------------
You say "should" but then "assert" below. I think the should is correct though...

================
Comment at: lib/Transforms/Utils/InlineFunction.cpp:804
@@ +803,3 @@
+          RV = OldCast->getOperand(0);
+        assert(cast<CallInst>(RV)->isMustTailCall());
+
----------------
So, I don't think you can *always* assert. What about a musttail call to a function that just happens to return the result of a non-musttail call? Above, you set the flag if any call is musttail, so it seems you should just continue if this call site isn't a musttail.

Similarly, I don't think you can assert that there will be a callinst here.

http://reviews.llvm.org/D3491






More information about the llvm-commits mailing list