forked from OSchip/llvm-project
[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 llvm-svn: 293648
This commit is contained in:
parent
62b83ede84
commit
a7c041d147
|
@ -286,6 +286,9 @@ namespace llvm {
|
||||||
/// the target platform.
|
/// the target platform.
|
||||||
extern char &XRayInstrumentationID;
|
extern char &XRayInstrumentationID;
|
||||||
|
|
||||||
|
/// This pass inserts FEntry calls
|
||||||
|
extern char &FEntryInserterID;
|
||||||
|
|
||||||
/// \brief This pass implements the "patchable-function" attribute.
|
/// \brief This pass implements the "patchable-function" attribute.
|
||||||
extern char &PatchableFunctionID;
|
extern char &PatchableFunctionID;
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ void initializeGVNHoistLegacyPassPass(PassRegistry &);
|
||||||
void initializeExpandISelPseudosPass(PassRegistry&);
|
void initializeExpandISelPseudosPass(PassRegistry&);
|
||||||
void initializeExpandPostRAPass(PassRegistry&);
|
void initializeExpandPostRAPass(PassRegistry&);
|
||||||
void initializeExternalAAWrapperPassPass(PassRegistry&);
|
void initializeExternalAAWrapperPassPass(PassRegistry&);
|
||||||
|
void initializeFEntryInserterPass(PassRegistry &);
|
||||||
void initializeFinalizeMachineBundlesPass(PassRegistry&);
|
void initializeFinalizeMachineBundlesPass(PassRegistry&);
|
||||||
void initializeFlattenCFGPassPass(PassRegistry&);
|
void initializeFlattenCFGPassPass(PassRegistry&);
|
||||||
void initializeFloat2IntLegacyPassPass(PassRegistry&);
|
void initializeFloat2IntLegacyPassPass(PassRegistry&);
|
||||||
|
|
|
@ -998,6 +998,15 @@ def PATCHABLE_TAIL_CALL : Instruction {
|
||||||
let hasSideEffects = 1;
|
let hasSideEffects = 1;
|
||||||
let isReturn = 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.
|
// Generic opcodes used in GlobalISel.
|
||||||
include "llvm/Target/GenericOpcodes.td"
|
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.
|
/// that must lie within the function and not contain another stackmap.
|
||||||
HANDLE_TARGET_OPCODE(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
|
/// Patchable call instruction - this instruction represents a call to a
|
||||||
/// constant address, followed by a series of NOPs. It is intended to
|
/// constant address, followed by a series of NOPs. It is intended to
|
||||||
/// support optimizations for dynamic languages (such as javascript) that
|
/// support optimizations for dynamic languages (such as javascript) that
|
||||||
|
|
|
@ -23,6 +23,7 @@ add_llvm_library(LLVMCodeGen
|
||||||
ExpandISelPseudos.cpp
|
ExpandISelPseudos.cpp
|
||||||
ExpandPostRAPseudos.cpp
|
ExpandPostRAPseudos.cpp
|
||||||
FaultMaps.cpp
|
FaultMaps.cpp
|
||||||
|
FEntryInserter.cpp
|
||||||
FuncletLayout.cpp
|
FuncletLayout.cpp
|
||||||
GCMetadata.cpp
|
GCMetadata.cpp
|
||||||
GCMetadataPrinter.cpp
|
GCMetadataPrinter.cpp
|
||||||
|
|
|
@ -32,6 +32,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
|
||||||
initializeExpandISelPseudosPass(Registry);
|
initializeExpandISelPseudosPass(Registry);
|
||||||
initializeExpandPostRAPass(Registry);
|
initializeExpandPostRAPass(Registry);
|
||||||
initializeFinalizeMachineBundlesPass(Registry);
|
initializeFinalizeMachineBundlesPass(Registry);
|
||||||
|
initializeFEntryInserterPass(Registry);
|
||||||
initializeFuncletLayoutPass(Registry);
|
initializeFuncletLayoutPass(Registry);
|
||||||
initializeGCMachineCodeAnalysisPass(Registry);
|
initializeGCMachineCodeAnalysisPass(Registry);
|
||||||
initializeGCModuleInfoPass(Registry);
|
initializeGCModuleInfoPass(Registry);
|
||||||
|
|
|
@ -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(&StackMapLivenessID, false);
|
||||||
addPass(&LiveDebugValuesID, false);
|
addPass(&LiveDebugValuesID, false);
|
||||||
|
|
||||||
|
// Insert before XRay Instrumentation.
|
||||||
|
addPass(&FEntryInserterID, false);
|
||||||
|
|
||||||
addPass(&XRayInstrumentationID, false);
|
addPass(&XRayInstrumentationID, false);
|
||||||
addPass(&PatchableFunctionID, 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_RET(const MachineInstr &MI, X86MCInstLower &MCIL);
|
||||||
void LowerPATCHABLE_TAIL_CALL(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
|
// Helper function that emits the XRay sleds we've collected for a particular
|
||||||
// function.
|
// function.
|
||||||
void EmitXRayTable();
|
void EmitXRayTable();
|
||||||
|
|
|
@ -919,6 +919,19 @@ void X86AsmPrinter::LowerFAULTING_LOAD_OP(const MachineInstr &MI,
|
||||||
OutStreamer->EmitInstruction(LoadMI, getSubtargetInfo());
|
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,
|
void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI,
|
||||||
X86MCInstLower &MCIL) {
|
X86MCInstLower &MCIL) {
|
||||||
// PATCHABLE_OP minsize, opcode, operands
|
// PATCHABLE_OP minsize, opcode, operands
|
||||||
|
@ -1377,6 +1390,9 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||||
case TargetOpcode::FAULTING_LOAD_OP:
|
case TargetOpcode::FAULTING_LOAD_OP:
|
||||||
return LowerFAULTING_LOAD_OP(*MI, MCInstLowering);
|
return LowerFAULTING_LOAD_OP(*MI, MCInstLowering);
|
||||||
|
|
||||||
|
case TargetOpcode::FENTRY_CALL:
|
||||||
|
return LowerFENTRY_CALL(*MI, MCInstLowering);
|
||||||
|
|
||||||
case TargetOpcode::PATCHABLE_OP:
|
case TargetOpcode::PATCHABLE_OP:
|
||||||
return LowerPATCHABLE_OP(*MI, MCInstLowering);
|
return LowerPATCHABLE_OP(*MI, MCInstLowering);
|
||||||
|
|
||||||
|
|
|
@ -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