mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
PatchableFunction: Skip pseudos that do not create code
This fixes http://llvm.org/PR28524 llvm-svn: 275278
This commit is contained in:
parent
573e95bc54
commit
9e8e8522ad
@ -37,6 +37,22 @@ struct PatchableFunction : public MachineFunctionPass {
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns true if instruction \p MI will not result in actual machine code
|
||||
/// instructions.
|
||||
static bool doesNotGeneratecode(const MachineInstr &MI) {
|
||||
// TODO: Introduce an MCInstrDesc flag for this
|
||||
switch (MI.getOpcode()) {
|
||||
default: return false;
|
||||
case TargetOpcode::IMPLICIT_DEF:
|
||||
case TargetOpcode::KILL:
|
||||
case TargetOpcode::CFI_INSTRUCTION:
|
||||
case TargetOpcode::EH_LABEL:
|
||||
case TargetOpcode::GC_LABEL:
|
||||
case TargetOpcode::DBG_VALUE:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (!MF.getFunction()->hasFnAttribute("patchable-function"))
|
||||
return false;
|
||||
@ -48,18 +64,20 @@ bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
|
||||
#endif
|
||||
|
||||
auto &FirstMBB = *MF.begin();
|
||||
auto &FirstMI = *FirstMBB.begin();
|
||||
MachineBasicBlock::iterator FirstActualI = FirstMBB.begin();
|
||||
for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI)
|
||||
assert(FirstActualI != FirstMBB.end());
|
||||
|
||||
auto *TII = MF.getSubtarget().getInstrInfo();
|
||||
auto MIB = BuildMI(FirstMBB, FirstMBB.begin(), FirstMI.getDebugLoc(),
|
||||
auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(),
|
||||
TII->get(TargetOpcode::PATCHABLE_OP))
|
||||
.addImm(2)
|
||||
.addImm(FirstMI.getOpcode());
|
||||
.addImm(FirstActualI->getOpcode());
|
||||
|
||||
for (auto &MO : FirstMI.operands())
|
||||
for (auto &MO : FirstActualI->operands())
|
||||
MIB.addOperand(MO);
|
||||
|
||||
FirstMI.eraseFromParent();
|
||||
FirstActualI->eraseFromParent();
|
||||
MF.ensureAlignment(4);
|
||||
return true;
|
||||
}
|
||||
|
@ -41,3 +41,27 @@ define void @f3() "patchable-function"="prologue-short-redirect" optsize {
|
||||
; CHECK-ALIGN: _f3:
|
||||
ret void
|
||||
}
|
||||
|
||||
; This testcase happens to produce a KILL instruction at the beginning of the
|
||||
; first basic block. In this case the 2nd instruction should be turned into a
|
||||
; patchable one.
|
||||
; CHECK-LABEL: f4:
|
||||
; CHECK-NEXT: 8b 0c 37 movl (%rdi,%rsi), %ecx
|
||||
define i32 @f4(i8* %arg1, i64 %arg2, i32 %arg3) "patchable-function"="prologue-short-redirect" {
|
||||
bb:
|
||||
%tmp10 = getelementptr i8, i8* %arg1, i64 %arg2
|
||||
%tmp11 = bitcast i8* %tmp10 to i32*
|
||||
%tmp12 = load i32, i32* %tmp11, align 4
|
||||
fence acquire
|
||||
%tmp13 = add i32 %tmp12, %arg3
|
||||
%tmp14 = cmpxchg i32* %tmp11, i32 %tmp12, i32 %tmp13 seq_cst monotonic
|
||||
%tmp15 = extractvalue { i32, i1 } %tmp14, 1
|
||||
br i1 %tmp15, label %bb21, label %bb16
|
||||
|
||||
bb16:
|
||||
br label %bb21
|
||||
|
||||
bb21:
|
||||
%tmp22 = phi i32 [ %tmp12, %bb ], [ %arg3, %bb16 ]
|
||||
ret i32 %tmp22
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user