[llvm] r329385 - EntryExitInstrumenter: Handle musttail calls

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 6 03:14:09 PDT 2018


Author: hans
Date: Fri Apr  6 03:14:09 2018
New Revision: 329385

URL: http://llvm.org/viewvc/llvm-project?rev=329385&view=rev
Log:
EntryExitInstrumenter: Handle musttail calls

Inserting instrumentation between a musttail call and ret instruction
would create invalid IR. Instead, treat musttail calls as function
exits.

Modified:
    llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp
    llvm/trunk/test/Transforms/EntryExitInstrumenter/mcount.ll

Modified: llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp?rev=329385&r1=329384&r2=329385&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/EntryExitInstrumenter.cpp Fri Apr  6 03:14:09 2018
@@ -91,17 +91,27 @@ static bool runOnFunction(Function &F, b
 
   if (!ExitFunc.empty()) {
     for (BasicBlock &BB : F) {
-      TerminatorInst *T = BB.getTerminator();
+      Instruction *T = BB.getTerminator();
+      if (!isa<ReturnInst>(T))
+        continue;
+
+      // If T is preceded by a musttail call, that's the real terminator.
+      Instruction *Prev = T->getPrevNode();
+      if (BitCastInst *BCI = dyn_cast_or_null<BitCastInst>(Prev))
+        Prev = BCI->getPrevNode();
+      if (CallInst *CI = dyn_cast_or_null<CallInst>(Prev)) {
+        if (CI->isMustTailCall())
+          T = CI;
+      }
+
       DebugLoc DL;
       if (DebugLoc TerminatorDL = T->getDebugLoc())
         DL = TerminatorDL;
       else if (auto SP = F.getSubprogram())
         DL = DebugLoc::get(0, 0, SP);
 
-      if (isa<ReturnInst>(T)) {
-        insertCall(F, ExitFunc, T, DL);
-        Changed = true;
-      }
+      insertCall(F, ExitFunc, T, DL);
+      Changed = true;
     }
     F.removeAttribute(AttributeList::FunctionIndex, ExitAttr);
   }

Modified: llvm/trunk/test/Transforms/EntryExitInstrumenter/mcount.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/EntryExitInstrumenter/mcount.ll?rev=329385&r1=329384&r2=329385&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/EntryExitInstrumenter/mcount.ll (original)
+++ llvm/trunk/test/Transforms/EntryExitInstrumenter/mcount.ll Fri Apr  6 03:14:09 2018
@@ -44,7 +44,6 @@ entry:
 ; CHECK-NEXT ret void
 }
 
-attributes #0 = { "instrument-function-entry-inlined"="mcount" "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" }
 
 
 ; The mcount function has many different names.
@@ -78,10 +77,33 @@ define void @f7() #7 { entry: ret void }
 ; CHECK: call void @__cyg_profile_func_enter_bare
 
 
+; Treat musttail calls as terminators; inserting between the musttail call and
+; ret is not allowed.
+declare i32* @tailcallee()
+define i32* @tailcaller() #8 {
+  %1 = musttail call i32* @tailcallee()
+  ret i32* %1
+; CHECK-LABEL: define i32* @tailcaller
+; CHECK: call void @__cyg_profile_func_exit
+; CHECK: musttail call i32* @tailcallee
+; CHECK: ret
+}
+define i8* @tailcaller2() #8 {
+  %1 = musttail call i32* @tailcallee()
+  %2 = bitcast i32* %1 to i8*
+  ret i8* %2
+; CHECK-LABEL: define i8* @tailcaller2
+; CHECK: call void @__cyg_profile_func_exit
+; CHECK: musttail call i32* @tailcallee
+; CHECK: bitcast
+; CHECK: ret
+}
+
 ; The attributes are "consumed" when the instrumentation is inserted.
 ; CHECK: attributes
 ; CHECK-NOT: instrument-function
 
+attributes #0 = { "instrument-function-entry-inlined"="mcount" "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" }
 attributes #1 = { "instrument-function-entry-inlined"=".mcount" }
 attributes #2 = { "instrument-function-entry-inlined"="\01__gnu_mcount_nc" }
 attributes #3 = { "instrument-function-entry-inlined"="\01_mcount" }
@@ -89,3 +111,4 @@ attributes #4 = { "instrument-function-e
 attributes #5 = { "instrument-function-entry-inlined"="__mcount" }
 attributes #6 = { "instrument-function-entry-inlined"="_mcount" }
 attributes #7 = { "instrument-function-entry-inlined"="__cyg_profile_func_enter_bare" }
+attributes #8 = { "instrument-function-exit"="__cyg_profile_func_exit" }




More information about the llvm-commits mailing list