[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:
Nirav Dave 2017-01-31 17:00:27 +00:00
parent 34d37a4707
commit 53d52e9e2b
11 changed files with 110 additions and 0 deletions

View File

@ -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;

View File

@ -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&);

View File

@ -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"

View File

@ -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

View File

@ -23,6 +23,7 @@ add_llvm_library(LLVMCodeGen
ExpandISelPseudos.cpp
ExpandPostRAPseudos.cpp
FaultMaps.cpp
FEntryInserter.cpp
FuncletLayout.cpp
GCMetadata.cpp
GCMetadataPrinter.cpp

View File

@ -32,6 +32,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeExpandISelPseudosPass(Registry);
initializeExpandPostRAPass(Registry);
initializeFinalizeMachineBundlesPass(Registry);
initializeFEntryInserterPass(Registry);
initializeFuncletLayoutPass(Registry);
initializeGCMachineCodeAnalysisPass(Registry);
initializeGCModuleInfoPass(Registry);

View 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)

View File

@ -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);

View File

@ -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();

View File

@ -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);

View 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" }