diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -2029,7 +2029,9 @@ /// Optional target hook that returns true if \p MBB is safe to outline from, /// and returns any target-specific information in \p Flags. virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, - unsigned &Flags) const; + unsigned &Flags) const { + return true; + } /// Optional target hook which partitions \p MBB into outlinable ranges for /// instruction mapping purposes. Each range is defined by two iterators: diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -1650,6 +1650,16 @@ case TargetOpcode::LIFETIME_START: case TargetOpcode::LIFETIME_END: return outliner::InstrType::Invisible; + + // Pseudo-instructions that must not be outlined + case TargetOpcode::FENTRY_CALL: + case TargetOpcode::PATCHABLE_FUNCTION_ENTER: + case TargetOpcode::PATCHABLE_FUNCTION_EXIT: + case TargetOpcode::PATCHABLE_EVENT_CALL: + case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL: + case TargetOpcode::PATCHABLE_RET: + case TargetOpcode::PATCHABLE_TAIL_CALL: + return outliner::InstrType::Illegal; default: break; } @@ -1697,31 +1707,3 @@ // If we don't know, delegate to the target-specific hook. return getOutliningTypeImpl(MIT, Flags); } - -bool TargetInstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, - unsigned &Flags) const { - // Some instrumentations create special TargetOpcode at the start which - // expands to special code sequences which must be present. - auto First = MBB.getFirstNonDebugInstr(); - if (First == MBB.end()) - return true; - - if (First->getOpcode() == TargetOpcode::FENTRY_CALL || - First->getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER) - return false; - - // Some instrumentations create special pseudo-instructions at or just before - // the end that must be present. - auto Last = MBB.getLastNonDebugInstr(); - if (Last->getOpcode() == TargetOpcode::PATCHABLE_RET || - Last->getOpcode() == TargetOpcode::PATCHABLE_TAIL_CALL) - return false; - - if (Last != First && Last->isReturn()) { - --Last; - if (Last->getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_EXIT || - Last->getOpcode() == TargetOpcode::PATCHABLE_TAIL_CALL) - return false; - } - return true; -} diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-patchable.mir b/llvm/test/CodeGen/AArch64/machine-outliner-patchable.mir --- a/llvm/test/CodeGen/AArch64/machine-outliner-patchable.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-patchable.mir @@ -1,4 +1,5 @@ -# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass machine-outliner -verify-machineinstrs -enable-machine-outliner %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass machine-outliner -verify-machineinstrs -enable-machine-outliner %s -o - | FileCheck %s -check-prefixes=CHECK,FUNCTION_A +# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass machine-outliner -verify-machineinstrs -enable-machine-outliner %s -o - | FileCheck %s -check-prefixes=CHECK,FUNCTION_B --- | ; Function Attrs: minsize declare void @foo(i32, i32, i32, i32) #0 @@ -47,20 +48,16 @@ machineFunctionInfo: hasRedZone: false body: | + ; COM: Make sure that PATCHABLE_FUNCTION_ENTER and PATCHABLE_FUNCTION_EXIT + ; COM: instructions aren't outlined. ; CHECK-LABEL: name: xray0 ; CHECK: bb.0.entry: ; CHECK: PATCHABLE_FUNCTION_ENTER ; CHECK: bb.1.if.then: - ; CHECK: BL @[[OUTLINED_FUNCTION:OUTLINED_FUNCTION_[0-9]]] + ; CHECK: BL @[[OUTLINED_FUNCTION_A:OUTLINED_FUNCTION_[0-9]]] ; CHECK: bb.2.if.end: - ; CHECK-NEXT: $w0 = MOVZWi 5, 0 - ; CHECK-NEXT: $w1 = MOVZWi 6, 0 - ; CHECK-NEXT: $w2 = MOVZWi 7, 0 - ; CHECK-NEXT: $w3 = MOVZWi 8, 0 - ; CHECK-NEXT: BL @foo, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit killed $w1, implicit killed $w2, implicit killed $w3, implicit-def $sp - ; CHECK: $w0 = MOVZWi 5, 0 - ; CHECK-NEXT: $w1 = MOVZWi 6, 0 - ; CHECK-NEXT: PATCHABLE_FUNCTION_EXIT + ; CHECK: BL @[[OUTLINED_FUNCTION_B:OUTLINED_FUNCTION_[0-9]]] + ; CHECK: PATCHABLE_FUNCTION_EXIT ; CHECK-NEXT: RET undef $lr bb.0.entry: @@ -109,16 +106,10 @@ ; CHECK: bb.0.entry: ; CHECK: PATCHABLE_FUNCTION_ENTER ; CHECK: bb.1.if.then: - ; CHECK: BL @[[OUTLINED_FUNCTION]] + ; CHECK: BL @[[OUTLINED_FUNCTION_A]] ; CHECK: bb.2.if.end: - ; CHECK-NEXT: $w0 = MOVZWi 5, 0 - ; CHECK-NEXT: $w1 = MOVZWi 6, 0 - ; CHECK-NEXT: $w2 = MOVZWi 7, 0 - ; CHECK-NEXT: $w3 = MOVZWi 8, 0 - ; CHECK-NEXT: BL @foo, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $w0, implicit killed $w1, implicit killed $w2, implicit killed $w3, implicit-def $sp - ; CHECK: $w0 = MOVZWi 5, 0 - ; CHECK-NEXT: $w1 = MOVZWi 6, 0 - ; CHECK-NEXT: PATCHABLE_FUNCTION_EXIT + ; CHECK: BL @[[OUTLINED_FUNCTION_B]] + ; CHECK: PATCHABLE_FUNCTION_EXIT ; CHECK-NEXT: RET undef $lr bb.0.entry: @@ -150,13 +141,20 @@ PATCHABLE_FUNCTION_EXIT RET undef $lr - ; CHECK: name: [[OUTLINED_FUNCTION]] - ; CHECK: bb.0: - ; CHECK: $w0 = MOVZWi 1, 0 - ; CHECK-NEXT: $w1 = MOVZWi 2, 0 - ; CHECK-NEXT: $w2 = MOVZWi 3, 0 - ; CHECK-NEXT: $w3 = MOVZWi 4, 0 - ; CHECK-NEXT: TCRETURNdi @foo, 0, implicit $sp + ; FUNCTION_A: name: [[OUTLINED_FUNCTION_A]] + ; FUNCTION_A: bb.0: + ; FUNCTION_A: $w0 = MOVZWi 1, 0 + ; FUNCTION_A-NEXT: $w1 = MOVZWi 2, 0 + ; FUNCTION_A-NEXT: $w2 = MOVZWi 3, 0 + ; FUNCTION_A-NEXT: $w3 = MOVZWi 4, 0 + ; FUNCTION_A-NEXT: TCRETURNdi @foo, 0, implicit $sp -... + ; FUNCTION_B: name: [[OUTLINED_FUNCTION_B]] + ; FUNCTION_B: bb.0: + ; FUNCTION_B: $w0 = MOVZWi 5, 0 + ; FUNCTION_B-NEXT: $w1 = MOVZWi 6, 0 + ; FUNCTION_B-NEXT: $w2 = MOVZWi 7, 0 + ; FUNCTION_B-NEXT: $w3 = MOVZWi 8, 0 + ; FUNCTION_B-NEXT: TCRETURNdi @foo, 0, implicit $sp +... diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll b/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll --- a/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll +++ b/llvm/test/CodeGen/RISCV/machine-outliner-patchable.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: # %bb.0: ; CHECK-NEXT: # FEntry call ; CHECK: # %bb.1: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 +; CHECK-NEXT: call t0, [[OUTLINED_FUNCTION:OUTLINED_FUNCTION_[0-9]+]] entry: br i1 %a, label %if.then, label %if.end if.then: @@ -27,7 +27,7 @@ ; CHECK-NEXT: # %bb.0: ; CHECK-NEXT: # FEntry call ; CHECK: # %bb.1: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 +; CHECK-NEXT: call t0, [[OUTLINED_FUNCTION]] entry: br i1 %a, label %if.then, label %if.end if.then: @@ -47,7 +47,7 @@ ; CHECK-NEXT: nop ; CHECK-NEXT: nop ; CHECK: # %bb.1: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 +; CHECK-NEXT: call t0, [[OUTLINED_FUNCTION]] entry: br i1 %a, label %if.then, label %if.end if.then: @@ -65,7 +65,7 @@ ; CHECK-NEXT: nop ; CHECK-NEXT: nop ; CHECK: # %bb.1: -; CHECK-NEXT: call t0, OUTLINED_FUNCTION_1 +; CHECK-NEXT: call t0, [[OUTLINED_FUNCTION]] entry: br i1 %a, label %if.then, label %if.end if.then: @@ -75,3 +75,12 @@ call void @foo(i32 5, i32 6, i32 7, i32 8) ret void } + +;; Make sure that OUTLINED_FUNCTION contains the right instructions +; CHECK: [[OUTLINED_FUNCTION]]: +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: li a0, 1 +; CHECK-NEXT: li a1, 2 +; CHECK-NEXT: li a2, 3 +; CHECK-NEXT: li a3, 4 +; CHECK-NEXT: jr t0 \ No newline at end of file