[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