forked from OSchip/llvm-project
[SystemZ] Provide size values for PATCHPOINT, STACKMAP and FENTRY_CALL.
All instructions must have a correct size value close to emission when SystemZLongBranch runs, or a necessary branch relaxation may be missed. This patch also adds an assert for instruction sizes in SystemZLongBranch. Review: Ulrich Weigand
This commit is contained in:
parent
c3dce37a55
commit
9f8872779a
|
@ -27,6 +27,7 @@
|
||||||
#include "llvm/CodeGen/MachineOperand.h"
|
#include "llvm/CodeGen/MachineOperand.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/SlotIndexes.h"
|
#include "llvm/CodeGen/SlotIndexes.h"
|
||||||
|
#include "llvm/CodeGen/StackMaps.h"
|
||||||
#include "llvm/CodeGen/TargetInstrInfo.h"
|
#include "llvm/CodeGen/TargetInstrInfo.h"
|
||||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||||
#include "llvm/MC/MCInstrDesc.h"
|
#include "llvm/MC/MCInstrDesc.h"
|
||||||
|
@ -1515,6 +1516,13 @@ unsigned SystemZInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
|
||||||
const char *AsmStr = MI.getOperand(0).getSymbolName();
|
const char *AsmStr = MI.getOperand(0).getSymbolName();
|
||||||
return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
|
return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
|
||||||
}
|
}
|
||||||
|
else if (MI.getOpcode() == SystemZ::PATCHPOINT)
|
||||||
|
return PatchPointOpers(&MI).getNumPatchBytes();
|
||||||
|
else if (MI.getOpcode() == SystemZ::STACKMAP)
|
||||||
|
return MI.getOperand(1).getImm();
|
||||||
|
else if (MI.getOpcode() == SystemZ::FENTRY_CALL)
|
||||||
|
return 6;
|
||||||
|
|
||||||
return MI.getDesc().getSize();
|
return MI.getDesc().getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,10 +209,24 @@ void SystemZLongBranch::skipTerminator(BlockPosition &Position,
|
||||||
Position.Address += Terminator.ExtraRelaxSize;
|
Position.Address += Terminator.ExtraRelaxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned getInstSizeInBytes(const MachineInstr &MI,
|
||||||
|
const SystemZInstrInfo *TII) {
|
||||||
|
unsigned Size = TII->getInstSizeInBytes(MI);
|
||||||
|
assert((Size ||
|
||||||
|
// These do not have a size:
|
||||||
|
MI.isDebugOrPseudoInstr() || MI.isPosition() || MI.isKill() ||
|
||||||
|
MI.isImplicitDef() || MI.getOpcode() == SystemZ::MemBarrier ||
|
||||||
|
// These have a size that may be zero:
|
||||||
|
MI.isInlineAsm() || MI.getOpcode() == SystemZ::STACKMAP ||
|
||||||
|
MI.getOpcode() == SystemZ::PATCHPOINT) &&
|
||||||
|
"Missing size value for instruction.");
|
||||||
|
return Size;
|
||||||
|
}
|
||||||
|
|
||||||
// Return a description of terminator instruction MI.
|
// Return a description of terminator instruction MI.
|
||||||
TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr &MI) {
|
TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr &MI) {
|
||||||
TerminatorInfo Terminator;
|
TerminatorInfo Terminator;
|
||||||
Terminator.Size = TII->getInstSizeInBytes(MI);
|
Terminator.Size = getInstSizeInBytes(MI, TII);
|
||||||
if (MI.isConditionalBranch() || MI.isUnconditionalBranch()) {
|
if (MI.isConditionalBranch() || MI.isUnconditionalBranch()) {
|
||||||
switch (MI.getOpcode()) {
|
switch (MI.getOpcode()) {
|
||||||
case SystemZ::J:
|
case SystemZ::J:
|
||||||
|
@ -287,7 +301,7 @@ uint64_t SystemZLongBranch::initMBBInfo() {
|
||||||
MachineBasicBlock::iterator MI = MBB->begin();
|
MachineBasicBlock::iterator MI = MBB->begin();
|
||||||
MachineBasicBlock::iterator End = MBB->end();
|
MachineBasicBlock::iterator End = MBB->end();
|
||||||
while (MI != End && !MI->isTerminator()) {
|
while (MI != End && !MI->isTerminator()) {
|
||||||
Block.Size += TII->getInstSizeInBytes(*MI);
|
Block.Size += getInstSizeInBytes(*MI, TII);
|
||||||
++MI;
|
++MI;
|
||||||
}
|
}
|
||||||
skipNonTerminators(Position, Block);
|
skipNonTerminators(Position, Block);
|
||||||
|
|
|
@ -97,6 +97,59 @@ entry:
|
||||||
ret i64 %result
|
ret i64 %result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; Test that the number of bytes is reflected in the instruction size and
|
||||||
|
; therefore cause relaxation of the initial branch.
|
||||||
|
define void @patchpoint_size(i32 %Arg) {
|
||||||
|
; CHECK-LABEL: patchpoint_size:
|
||||||
|
; CHECK: # %bb.0:
|
||||||
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
||||||
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
||||||
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
||||||
|
; CHECK-NEXT: aghi %r15, -160
|
||||||
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
||||||
|
; CHECK-NEXT: chi %r2, 0
|
||||||
|
; CHECK-NEXT: jge .LBB6_2
|
||||||
|
%c = icmp eq i32 %Arg, 0
|
||||||
|
br i1 %c, label %block0, label %patch1
|
||||||
|
|
||||||
|
block0:
|
||||||
|
call i64 @foo(i64 0, i64 0)
|
||||||
|
br label %exit
|
||||||
|
|
||||||
|
patch1:
|
||||||
|
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 0, i32 65536, i8* null, i32 0)
|
||||||
|
br label %exit
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @stackmap_size(i32 %Arg) {
|
||||||
|
; CHECK-LABEL: stackmap_size:
|
||||||
|
; CHECK: # %bb.0:
|
||||||
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
||||||
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
||||||
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
||||||
|
; CHECK-NEXT: aghi %r15, -160
|
||||||
|
; CHECK-NEXT: .cfi_def_cfa_offset 320
|
||||||
|
; CHECK-NEXT: chi %r2, 0
|
||||||
|
; CHECK-NEXT: jge .LBB7_2
|
||||||
|
%c = icmp eq i32 %Arg, 0
|
||||||
|
br i1 %c, label %block0, label %stackmap1
|
||||||
|
|
||||||
|
block0:
|
||||||
|
call i64 @foo(i64 0, i64 0)
|
||||||
|
br label %exit
|
||||||
|
|
||||||
|
stackmap1:
|
||||||
|
call void (i64, i32, ...) @llvm.experimental.stackmap(i64 1, i32 65536)
|
||||||
|
br label %exit
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
declare void @llvm.experimental.stackmap(i64, i32, ...)
|
declare void @llvm.experimental.stackmap(i64, i32, ...)
|
||||||
declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
|
declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
|
||||||
declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)
|
declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)
|
||||||
|
|
Loading…
Reference in New Issue