mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-23 11:49:50 +00:00
[X86] Implement -mfentry
Summary: Insert calls to __fentry__ at function entry. Reviewers: hfinkel, craig.topper Subscribers: mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D28000 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293648 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
34d37a4707
commit
53d52e9e2b
@ -286,6 +286,9 @@ namespace llvm {
|
||||
/// the target platform.
|
||||
extern char &XRayInstrumentationID;
|
||||
|
||||
/// This pass inserts FEntry calls
|
||||
extern char &FEntryInserterID;
|
||||
|
||||
/// \brief This pass implements the "patchable-function" attribute.
|
||||
extern char &PatchableFunctionID;
|
||||
|
||||
|
@ -131,6 +131,7 @@ void initializeGVNHoistLegacyPassPass(PassRegistry &);
|
||||
void initializeExpandISelPseudosPass(PassRegistry&);
|
||||
void initializeExpandPostRAPass(PassRegistry&);
|
||||
void initializeExternalAAWrapperPassPass(PassRegistry&);
|
||||
void initializeFEntryInserterPass(PassRegistry &);
|
||||
void initializeFinalizeMachineBundlesPass(PassRegistry&);
|
||||
void initializeFlattenCFGPassPass(PassRegistry&);
|
||||
void initializeFloat2IntLegacyPassPass(PassRegistry&);
|
||||
|
@ -998,6 +998,15 @@ def PATCHABLE_TAIL_CALL : Instruction {
|
||||
let hasSideEffects = 1;
|
||||
let isReturn = 1;
|
||||
}
|
||||
def FENTRY_CALL : Instruction {
|
||||
let OutOperandList = (outs unknown:$dst);
|
||||
let InOperandList = (ins variable_ops);
|
||||
let AsmString = "# FEntry call";
|
||||
let usesCustomInserter = 1;
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
let hasSideEffects = 1;
|
||||
}
|
||||
|
||||
// Generic opcodes used in GlobalISel.
|
||||
include "llvm/Target/GenericOpcodes.td"
|
||||
|
@ -107,6 +107,9 @@ HANDLE_TARGET_OPCODE(LIFETIME_END)
|
||||
/// that must lie within the function and not contain another stackmap.
|
||||
HANDLE_TARGET_OPCODE(STACKMAP)
|
||||
|
||||
/// FEntry all - This is a marker instruction which gets translated into a raw fentry call.
|
||||
HANDLE_TARGET_OPCODE(FENTRY_CALL)
|
||||
|
||||
/// Patchable call instruction - this instruction represents a call to a
|
||||
/// constant address, followed by a series of NOPs. It is intended to
|
||||
/// support optimizations for dynamic languages (such as javascript) that
|
||||
|
@ -23,6 +23,7 @@ add_llvm_library(LLVMCodeGen
|
||||
ExpandISelPseudos.cpp
|
||||
ExpandPostRAPseudos.cpp
|
||||
FaultMaps.cpp
|
||||
FEntryInserter.cpp
|
||||
FuncletLayout.cpp
|
||||
GCMetadata.cpp
|
||||
GCMetadataPrinter.cpp
|
||||
|
@ -32,6 +32,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
|
||||
initializeExpandISelPseudosPass(Registry);
|
||||
initializeExpandPostRAPass(Registry);
|
||||
initializeFinalizeMachineBundlesPass(Registry);
|
||||
initializeFEntryInserterPass(Registry);
|
||||
initializeFuncletLayoutPass(Registry);
|
||||
initializeGCMachineCodeAnalysisPass(Registry);
|
||||
initializeGCModuleInfoPass(Registry);
|
||||
|
55
lib/CodeGen/FEntryInserter.cpp
Normal file
55
lib/CodeGen/FEntryInserter.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
//===-- FEntryInsertion.cpp - Patchable prologues for LLVM -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file edits function bodies to insert fentry calls.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
struct FEntryInserter : public MachineFunctionPass {
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
FEntryInserter() : MachineFunctionPass(ID) {
|
||||
initializeFEntryInserterPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &F) override;
|
||||
};
|
||||
}
|
||||
|
||||
bool FEntryInserter::runOnMachineFunction(MachineFunction &MF) {
|
||||
const std::string FEntryName =
|
||||
MF.getFunction()->getFnAttribute("fentry-call").getValueAsString();
|
||||
if (FEntryName != "true")
|
||||
return false;
|
||||
|
||||
auto &FirstMBB = *MF.begin();
|
||||
auto &FirstMI = *FirstMBB.begin();
|
||||
|
||||
auto *TII = MF.getSubtarget().getInstrInfo();
|
||||
BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(),
|
||||
TII->get(TargetOpcode::FENTRY_CALL));
|
||||
return true;
|
||||
}
|
||||
|
||||
char FEntryInserter::ID = 0;
|
||||
char &llvm::FEntryInserterID = FEntryInserter::ID;
|
||||
INITIALIZE_PASS(FEntryInserter, "fentry-insert", "Insert fentry calls", false,
|
||||
false)
|
@ -668,6 +668,9 @@ void TargetPassConfig::addMachinePasses() {
|
||||
addPass(&StackMapLivenessID, false);
|
||||
addPass(&LiveDebugValuesID, false);
|
||||
|
||||
// Insert before XRay Instrumentation.
|
||||
addPass(&FEntryInserterID, false);
|
||||
|
||||
addPass(&XRayInstrumentationID, false);
|
||||
addPass(&PatchableFunctionID, false);
|
||||
|
||||
|
@ -92,6 +92,8 @@ class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
|
||||
void LowerPATCHABLE_RET(const MachineInstr &MI, X86MCInstLower &MCIL);
|
||||
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
|
||||
|
||||
void LowerFENTRY_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
|
||||
|
||||
// Helper function that emits the XRay sleds we've collected for a particular
|
||||
// function.
|
||||
void EmitXRayTable();
|
||||
|
@ -919,6 +919,19 @@ void X86AsmPrinter::LowerFAULTING_LOAD_OP(const MachineInstr &MI,
|
||||
OutStreamer->EmitInstruction(LoadMI, getSubtargetInfo());
|
||||
}
|
||||
|
||||
void X86AsmPrinter::LowerFENTRY_CALL(const MachineInstr &MI,
|
||||
X86MCInstLower &MCIL) {
|
||||
bool Is64Bits = Subtarget->is64Bit();
|
||||
MCContext &Ctx = OutStreamer->getContext();
|
||||
MCSymbol *fentry = Ctx.getOrCreateSymbol("__fentry__");
|
||||
const MCSymbolRefExpr *Op =
|
||||
MCSymbolRefExpr::create(fentry, MCSymbolRefExpr::VK_None, Ctx);
|
||||
|
||||
EmitAndCountInstruction(
|
||||
MCInstBuilder(Is64Bits ? X86::CALL64pcrel32 : X86::CALLpcrel32)
|
||||
.addExpr(Op));
|
||||
}
|
||||
|
||||
void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI,
|
||||
X86MCInstLower &MCIL) {
|
||||
// PATCHABLE_OP minsize, opcode, operands
|
||||
@ -1377,6 +1390,9 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
case TargetOpcode::FAULTING_LOAD_OP:
|
||||
return LowerFAULTING_LOAD_OP(*MI, MCInstLowering);
|
||||
|
||||
case TargetOpcode::FENTRY_CALL:
|
||||
return LowerFENTRY_CALL(*MI, MCInstLowering);
|
||||
|
||||
case TargetOpcode::PATCHABLE_OP:
|
||||
return LowerPATCHABLE_OP(*MI, MCInstLowering);
|
||||
|
||||
|
16
test/CodeGen/X86/fentry-insertion.ll
Normal file
16
test/CodeGen/X86/fentry-insertion.ll
Normal file
@ -0,0 +1,16 @@
|
||||
; RUN: llc %s -o - | FileCheck %s
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @test1() #0 {
|
||||
entry:
|
||||
ret void
|
||||
|
||||
; CHECK-LABEL: @test1
|
||||
; CHECK: callq __fentry__
|
||||
; CHECK-NOT: mcount
|
||||
; CHECK: retq
|
||||
}
|
||||
|
||||
attributes #0 = { "fentry-call"="true" }
|
||||
|
Loading…
Reference in New Issue
Block a user