forked from OSchip/llvm-project
[SystemZ] Emit EXRL target instructions before text section is ended.
SystemZ adds the EXRL target instructions in the end of each file. This must be done before debug info emission since that may end the text section, and therefore this is now done in emitConstantPools() (instead of in emitEndOfAsmFile). Review: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D109513
This commit is contained in:
parent
ea27dd7497
commit
a48b43f981
|
@ -11,6 +11,7 @@
|
|||
#include "SystemZMCAsmInfo.h"
|
||||
#include "SystemZTargetStreamer.h"
|
||||
#include "TargetInfo/SystemZTargetInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDwarf.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
|
@ -183,6 +184,21 @@ static MCInstPrinter *createSystemZMCInstPrinter(const Triple &T,
|
|||
return new SystemZInstPrinter(MAI, MII, MRI);
|
||||
}
|
||||
|
||||
void SystemZTargetStreamer::emitConstantPools() {
|
||||
// Emit EXRL target instructions.
|
||||
if (EXRLTargets2Sym.empty())
|
||||
return;
|
||||
// Switch to the .text section.
|
||||
const MCObjectFileInfo &OFI = *Streamer.getContext().getObjectFileInfo();
|
||||
Streamer.SwitchSection(OFI.getTextSection());
|
||||
for (auto &I : EXRLTargets2Sym) {
|
||||
Streamer.emitLabel(I.second);
|
||||
const MCInstSTIPair &MCI_STI = I.first;
|
||||
Streamer.emitInstruction(MCI_STI.first, *MCI_STI.second);
|
||||
}
|
||||
EXRLTargets2Sym.clear();
|
||||
}
|
||||
|
||||
namespace {
|
||||
class SystemZTargetAsmStreamer : public SystemZTargetStreamer {
|
||||
formatted_raw_ostream &OS;
|
||||
|
|
|
@ -549,15 +549,17 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
|
|||
Register SrcReg = MI->getOperand(4).getReg();
|
||||
int64_t SrcDisp = MI->getOperand(5).getImm();
|
||||
|
||||
SystemZTargetStreamer *TS = getTargetStreamer();
|
||||
MCSymbol *DotSym = nullptr;
|
||||
MCInst ET = MCInstBuilder(TargetInsOpc).addReg(DestReg)
|
||||
.addImm(DestDisp).addImm(1).addReg(SrcReg).addImm(SrcDisp);
|
||||
MCInstSTIPair ET_STI(ET, &MF->getSubtarget());
|
||||
EXRLT2SymMap::iterator I = EXRLTargets2Sym.find(ET_STI);
|
||||
if (I != EXRLTargets2Sym.end())
|
||||
SystemZTargetStreamer::MCInstSTIPair ET_STI(ET, &MF->getSubtarget());
|
||||
SystemZTargetStreamer::EXRLT2SymMap::iterator I =
|
||||
TS->EXRLTargets2Sym.find(ET_STI);
|
||||
if (I != TS->EXRLTargets2Sym.end())
|
||||
DotSym = I->second;
|
||||
else
|
||||
EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol();
|
||||
TS->EXRLTargets2Sym[ET_STI] = DotSym = OutContext.createTempSymbol();
|
||||
const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
|
||||
EmitToStreamer(
|
||||
*OutStreamer,
|
||||
|
@ -722,19 +724,6 @@ void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
|
|||
getSubtargetInfo());
|
||||
}
|
||||
|
||||
void SystemZAsmPrinter::emitEXRLTargetInstructions() {
|
||||
if (EXRLTargets2Sym.empty())
|
||||
return;
|
||||
// Switch to the .text section.
|
||||
OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
|
||||
for (auto &I : EXRLTargets2Sym) {
|
||||
OutStreamer->emitLabel(I.second);
|
||||
const MCInstSTIPair &MCI_STI = I.first;
|
||||
OutStreamer->emitInstruction(MCI_STI.first, *MCI_STI.second);
|
||||
}
|
||||
EXRLTargets2Sym.clear();
|
||||
}
|
||||
|
||||
// Convert a SystemZ-specific constant pool modifier into the associated
|
||||
// MCSymbolRefExpr variant kind.
|
||||
static MCSymbolRefExpr::VariantKind
|
||||
|
@ -793,7 +782,6 @@ bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
|
|||
}
|
||||
|
||||
void SystemZAsmPrinter::emitEndOfAsmFile(Module &M) {
|
||||
emitEXRLTargetInstructions();
|
||||
emitStackMaps(SM);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "SystemZMCInstLower.h"
|
||||
#include "SystemZTargetMachine.h"
|
||||
#include "SystemZTargetStreamer.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/StackMaps.h"
|
||||
#include "llvm/MC/MCInstBuilder.h"
|
||||
|
@ -27,32 +28,11 @@ class LLVM_LIBRARY_VISIBILITY SystemZAsmPrinter : public AsmPrinter {
|
|||
private:
|
||||
StackMaps SM;
|
||||
|
||||
typedef std::pair<MCInst, const MCSubtargetInfo *> MCInstSTIPair;
|
||||
struct CmpMCInst {
|
||||
bool operator()(const MCInstSTIPair &MCI_STI_A,
|
||||
const MCInstSTIPair &MCI_STI_B) const {
|
||||
if (MCI_STI_A.second != MCI_STI_B.second)
|
||||
return uintptr_t(MCI_STI_A.second) < uintptr_t(MCI_STI_B.second);
|
||||
const MCInst &A = MCI_STI_A.first;
|
||||
const MCInst &B = MCI_STI_B.first;
|
||||
assert(A.getNumOperands() == B.getNumOperands() &&
|
||||
A.getNumOperands() == 5 && A.getOperand(2).getImm() == 1 &&
|
||||
B.getOperand(2).getImm() == 1 && "Unexpected EXRL target MCInst");
|
||||
if (A.getOpcode() != B.getOpcode())
|
||||
return A.getOpcode() < B.getOpcode();
|
||||
if (A.getOperand(0).getReg() != B.getOperand(0).getReg())
|
||||
return A.getOperand(0).getReg() < B.getOperand(0).getReg();
|
||||
if (A.getOperand(1).getImm() != B.getOperand(1).getImm())
|
||||
return A.getOperand(1).getImm() < B.getOperand(1).getImm();
|
||||
if (A.getOperand(3).getReg() != B.getOperand(3).getReg())
|
||||
return A.getOperand(3).getReg() < B.getOperand(3).getReg();
|
||||
if (A.getOperand(4).getImm() != B.getOperand(4).getImm())
|
||||
return A.getOperand(4).getImm() < B.getOperand(4).getImm();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
typedef std::map<MCInstSTIPair, MCSymbol *, CmpMCInst> EXRLT2SymMap;
|
||||
EXRLT2SymMap EXRLTargets2Sym;
|
||||
SystemZTargetStreamer *getTargetStreamer() {
|
||||
MCTargetStreamer *TS = OutStreamer->getTargetStreamer();
|
||||
assert(TS && "do not have a target streamer");
|
||||
return static_cast<SystemZTargetStreamer *>(TS);
|
||||
}
|
||||
|
||||
public:
|
||||
SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
|
||||
|
@ -77,7 +57,6 @@ private:
|
|||
void LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &MCIL);
|
||||
void LowerSTACKMAP(const MachineInstr &MI);
|
||||
void LowerPATCHPOINT(const MachineInstr &MI, SystemZMCInstLower &Lower);
|
||||
void emitEXRLTargetInstructions();
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
|
|
|
@ -18,6 +18,35 @@ class SystemZTargetStreamer : public MCTargetStreamer {
|
|||
public:
|
||||
SystemZTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
|
||||
|
||||
typedef std::pair<MCInst, const MCSubtargetInfo *> MCInstSTIPair;
|
||||
struct CmpMCInst {
|
||||
bool operator()(const MCInstSTIPair &MCI_STI_A,
|
||||
const MCInstSTIPair &MCI_STI_B) const {
|
||||
if (MCI_STI_A.second != MCI_STI_B.second)
|
||||
return uintptr_t(MCI_STI_A.second) < uintptr_t(MCI_STI_B.second);
|
||||
const MCInst &A = MCI_STI_A.first;
|
||||
const MCInst &B = MCI_STI_B.first;
|
||||
assert(A.getNumOperands() == B.getNumOperands() &&
|
||||
A.getNumOperands() == 5 && A.getOperand(2).getImm() == 1 &&
|
||||
B.getOperand(2).getImm() == 1 && "Unexpected EXRL target MCInst");
|
||||
if (A.getOpcode() != B.getOpcode())
|
||||
return A.getOpcode() < B.getOpcode();
|
||||
if (A.getOperand(0).getReg() != B.getOperand(0).getReg())
|
||||
return A.getOperand(0).getReg() < B.getOperand(0).getReg();
|
||||
if (A.getOperand(1).getImm() != B.getOperand(1).getImm())
|
||||
return A.getOperand(1).getImm() < B.getOperand(1).getImm();
|
||||
if (A.getOperand(3).getReg() != B.getOperand(3).getReg())
|
||||
return A.getOperand(3).getReg() < B.getOperand(3).getReg();
|
||||
if (A.getOperand(4).getImm() != B.getOperand(4).getImm())
|
||||
return A.getOperand(4).getImm() < B.getOperand(4).getImm();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
typedef std::map<MCInstSTIPair, MCSymbol *, CmpMCInst> EXRLT2SymMap;
|
||||
EXRLT2SymMap EXRLTargets2Sym;
|
||||
|
||||
void emitConstantPools() override;
|
||||
|
||||
virtual void emitMachine(StringRef CPU) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
; RUN: llc < %s -mtriple=s390x-linux-gnu -generate-arange-section
|
||||
;
|
||||
; Test that the EXRL target instruction is emitted successfully (before text
|
||||
; section is closed).
|
||||
|
||||
@a = dso_local global i32* null, align 8, !dbg !0
|
||||
@j = dso_local global i32 0, align 4, !dbg !5
|
||||
|
||||
define void @fun() !dbg !14 {
|
||||
entry:
|
||||
%0 = load i32*, i32** @a, align 8, !dbg !18
|
||||
%1 = bitcast i32* %0 to i8*, !dbg !19
|
||||
%2 = load i32, i32* @j, align 4, !dbg !20
|
||||
%conv = sext i32 %2 to i64, !dbg !20
|
||||
call void @llvm.memset.p0i8.i64(i8* align 4 %1, i8 0, i64 %conv, i1 false), !dbg !19
|
||||
ret void, !dbg !21
|
||||
}
|
||||
|
||||
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1
|
||||
|
||||
!llvm.dbg.cu = !{!2}
|
||||
!llvm.module.flags = !{!9, !10, !11, !12}
|
||||
!llvm.ident = !{!13}
|
||||
|
||||
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
|
||||
!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true)
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
|
||||
!3 = !DIFile(filename: "file.c", directory: "")
|
||||
!4 = !{!0, !5}
|
||||
!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
|
||||
!6 = distinct !DIGlobalVariable(name: "j", scope: !2, file: !3, line: 2, type: !7, isLocal: false, isDefinition: true)
|
||||
!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
|
||||
!9 = !{i32 7, !"Dwarf Version", i32 4}
|
||||
!10 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!11 = !{i32 1, !"wchar_size", i32 4}
|
||||
!12 = !{i32 7, !"frame-pointer", i32 2}
|
||||
!13 = !{!"clang version 14.0.0"}
|
||||
!14 = distinct !DISubprogram(name: "fun", scope: !3, file: !3, line: 3, type: !15, scopeLine: 3, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17)
|
||||
!15 = !DISubroutineType(types: !16)
|
||||
!16 = !{null}
|
||||
!17 = !{}
|
||||
!18 = !DILocation(line: 4, column: 11, scope: !14)
|
||||
!19 = !DILocation(line: 4, column: 4, scope: !14)
|
||||
!20 = !DILocation(line: 4, column: 15, scope: !14)
|
||||
!21 = !DILocation(line: 5, column: 1, scope: !14)
|
Loading…
Reference in New Issue