summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/XRayInstrumentation.cpp1
-rw-r--r--llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp97
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstrInfo.cpp4
-rw-r--r--llvm/lib/Target/PowerPC/PPCSubtarget.h2
-rw-r--r--llvm/lib/XRay/InstrumentationMap.cpp3
5 files changed, 104 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/XRayInstrumentation.cpp b/llvm/lib/CodeGen/XRayInstrumentation.cpp
index 760683bc3bf..3cecda8c539 100644
--- a/llvm/lib/CodeGen/XRayInstrumentation.cpp
+++ b/llvm/lib/CodeGen/XRayInstrumentation.cpp
@@ -157,6 +157,7 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) {
case Triple::ArchType::arm:
case Triple::ArchType::thumb:
case Triple::ArchType::aarch64:
+ case Triple::ArchType::ppc64le:
// For the architectures which don't have a single return instruction
prependRetWithPatchableExit(MF, TII);
break;
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index f0e0ebc4946..b7cc5ec9db2 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -112,7 +112,9 @@ public:
void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK);
bool runOnMachineFunction(MachineFunction &MF) override {
Subtarget = &MF.getSubtarget<PPCSubtarget>();
- return AsmPrinter::runOnMachineFunction(MF);
+ bool Changed = AsmPrinter::runOnMachineFunction(MF);
+ emitXRayTable();
+ return Changed;
}
};
@@ -134,6 +136,7 @@ public:
void EmitFunctionBodyStart() override;
void EmitFunctionBodyEnd() override;
+ void EmitInstruction(const MachineInstr *MI) override;
};
/// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
@@ -1046,6 +1049,98 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
EmitToStreamer(*OutStreamer, TmpInst);
}
+void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) {
+ if (!Subtarget->isPPC64())
+ return PPCAsmPrinter::EmitInstruction(MI);
+
+ switch (MI->getOpcode()) {
+ default:
+ return PPCAsmPrinter::EmitInstruction(MI);
+ case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
+ // .begin:
+ // b .end # lis 0, FuncId[16..32]
+ // nop # li 0, FuncId[0..15]
+ // std 0, -8(1)
+ // mflr 0
+ // bl __xray_FunctionEntry
+ // mtlr 0
+ // .end:
+ //
+ // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
+ // of instructions change.
+ MCSymbol *BeginOfSled = OutContext.createTempSymbol();
+ MCSymbol *EndOfSled = OutContext.createTempSymbol();
+ OutStreamer->EmitLabel(BeginOfSled);
+ EmitToStreamer(*OutStreamer,
+ MCInstBuilder(PPC::B).addExpr(
+ MCSymbolRefExpr::create(EndOfSled, OutContext)));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
+ EmitToStreamer(
+ *OutStreamer,
+ MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
+ EmitToStreamer(*OutStreamer,
+ MCInstBuilder(PPC::BL8_NOP)
+ .addExpr(MCSymbolRefExpr::create(
+ OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
+ OutContext)));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
+ OutStreamer->EmitLabel(EndOfSled);
+ recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER);
+ break;
+ }
+ case TargetOpcode::PATCHABLE_FUNCTION_EXIT: {
+ // .p2align 3
+ // .begin:
+ // b(lr)? # lis 0, FuncId[16..32]
+ // nop # li 0, FuncId[0..15]
+ // std 0, -8(1)
+ // mflr 0
+ // bl __xray_FunctionExit
+ // mtlr 0
+ // .end:
+ // b(lr)?
+ //
+ // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
+ // of instructions change.
+ const MachineInstr *Next = [&] {
+ MachineBasicBlock::const_iterator It(MI);
+ const MachineBasicBlock *MBB = MI->getParent();
+ assert(It != MBB->end());
+ ++It;
+ assert(It->isReturn());
+ return &*It;
+ }();
+ OutStreamer->EmitCodeAlignment(8);
+ MCSymbol *BeginOfSled = OutContext.createTempSymbol();
+ OutStreamer->EmitLabel(BeginOfSled);
+ MCInst TmpInst;
+ LowerPPCMachineInstrToMCInst(Next, TmpInst, *this, false);
+ EmitToStreamer(*OutStreamer, TmpInst);
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
+ EmitToStreamer(
+ *OutStreamer,
+ MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
+ EmitToStreamer(*OutStreamer,
+ MCInstBuilder(PPC::BL8_NOP)
+ .addExpr(MCSymbolRefExpr::create(
+ OutContext.getOrCreateSymbol("__xray_FunctionExit"),
+ OutContext)));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
+ recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT);
+ break;
+ }
+ case TargetOpcode::PATCHABLE_TAIL_CALL:
+ case TargetOpcode::PATCHABLE_RET:
+ // PPC's tail call instruction, e.g. PPC::TCRETURNdi8, doesn't really
+ // lower to a PPC::B instruction. The PPC::B instruction is generated
+ // before it, and handled by the normal case.
+ llvm_unreachable("Tail call is handled in the normal case. See comments
+ around this assert.");
+ }
+}
+
void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
PPCTargetStreamer *TS =
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 315911db4e3..92fb2269427 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -65,7 +65,9 @@ UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden,
void PPCInstrInfo::anchor() {}
PPCInstrInfo::PPCInstrInfo(PPCSubtarget &STI)
- : PPCGenInstrInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP),
+ : PPCGenInstrInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP,
+ /* CatchRetOpcode */ -1,
+ STI.isPPC64() ? PPC::BLR8 : PPC::BLR),
Subtarget(STI), RI(STI.getTargetMachine()) {}
/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h
index 48d6365d3e7..5a97f595ad8 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.h
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h
@@ -318,6 +318,8 @@ public:
/// classifyGlobalReference - Classify a global variable reference for the
/// current subtarget accourding to how we should reference it.
unsigned char classifyGlobalReference(const GlobalValue *GV) const;
+
+ bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; }
};
} // End llvm namespace
diff --git a/llvm/lib/XRay/InstrumentationMap.cpp b/llvm/lib/XRay/InstrumentationMap.cpp
index b3b482f0286..431c251feb6 100644
--- a/llvm/lib/XRay/InstrumentationMap.cpp
+++ b/llvm/lib/XRay/InstrumentationMap.cpp
@@ -55,7 +55,8 @@ loadELF64(StringRef Filename, object::OwningBinary<object::ObjectFile> &ObjFile,
// Find the section named "xray_instr_map".
if (!ObjFile.getBinary()->isELF() ||
- ObjFile.getBinary()->getArch() != Triple::x86_64)
+ !(ObjFile.getBinary()->getArch() == Triple::x86_64 ||
+ ObjFile.getBinary()->getArch() == Triple::ppc64le))
return make_error<StringError>(
"File format not supported (only does ELF little endian 64-bit).",
std::make_error_code(std::errc::not_supported));
OpenPOWER on IntegriCloud