2013-02-20 00:38:32 +08:00
|
|
|
//===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===//
|
2005-07-02 06:44:09 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-07-02 06:44:09 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-08-14 00:26:38 +08:00
|
|
|
#ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
|
|
|
|
#define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
|
2005-07-02 06:44:09 +08:00
|
|
|
|
2014-03-19 14:53:25 +08:00
|
|
|
#include "X86Subtarget.h"
|
2008-06-28 19:08:27 +08:00
|
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
2015-06-16 02:44:08 +08:00
|
|
|
#include "llvm/CodeGen/FaultMaps.h"
|
2013-11-01 06:11:56 +08:00
|
|
|
#include "llvm/CodeGen/StackMaps.h"
|
2014-03-19 14:53:25 +08:00
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2005-07-02 06:44:09 +08:00
|
|
|
|
2014-07-25 04:40:55 +08:00
|
|
|
// Implemented in X86MCInstLower.cpp
|
|
|
|
namespace {
|
|
|
|
class X86MCInstLower;
|
|
|
|
}
|
|
|
|
|
2005-07-02 06:44:09 +08:00
|
|
|
namespace llvm {
|
2009-06-24 13:46:28 +08:00
|
|
|
class MCStreamer;
|
2014-05-04 08:03:41 +08:00
|
|
|
class MCSymbol;
|
2008-06-28 19:08:27 +08:00
|
|
|
|
2010-05-12 04:16:09 +08:00
|
|
|
class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
|
2008-06-28 19:08:27 +08:00
|
|
|
const X86Subtarget *Subtarget;
|
2013-11-01 06:11:56 +08:00
|
|
|
StackMaps SM;
|
2015-06-16 02:44:08 +08:00
|
|
|
FaultMaps FM;
|
2016-04-19 13:24:47 +08:00
|
|
|
std::unique_ptr<MCCodeEmitter> CodeEmitter;
|
[codeview] Implement FPO data assembler directives
Summary:
This adds a set of new directives that describe 32-bit x86 prologues.
The directives are limited and do not expose the full complexity of
codeview FPO data. They are merely a convenience for the compiler to
generate more readable assembly so we don't need to generate tons of
labels in CodeGen. If our prologue emission changes in the future, we
can change the set of available directives to suit our needs. These are
modelled after the .seh_ directives, which use a different format that
interacts with exception handling.
The directives are:
.cv_fpo_proc _foo
.cv_fpo_pushreg ebp/ebx/etc
.cv_fpo_setframe ebp/esi/etc
.cv_fpo_stackalloc 200
.cv_fpo_endprologue
.cv_fpo_endproc
.cv_fpo_data _foo
I tried to follow the implementation of ARM EHABI CFI directives by
sinking most directives out of MCStreamer and into X86TargetStreamer.
This helps avoid polluting non-X86 code with WinCOFF specific logic.
I used cdb to confirm that this can show locals in parent CSRs in a few
cases, most importantly the one where we use ESI as a frame pointer,
i.e. the one in http://crbug.com/756153#c28
Once we have cdb integration in debuginfo-tests, we can add integration
tests there.
Reviewers: majnemer, hans
Subscribers: aemerson, mgorny, kristof.beyls, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D38776
llvm-svn: 315513
2017-10-12 05:24:33 +08:00
|
|
|
bool EmitFPOData = false;
|
2013-11-01 06:11:56 +08:00
|
|
|
|
2014-07-25 04:40:55 +08:00
|
|
|
// This utility class tracks the length of a stackmap instruction's 'shadow'.
|
|
|
|
// It is used by the X86AsmPrinter to ensure that the stackmap shadow
|
|
|
|
// invariants (i.e. no other stackmaps, patchpoints, or control flow within
|
|
|
|
// the shadow) are met, while outputting a minimal number of NOPs for padding.
|
|
|
|
//
|
|
|
|
// To minimise the number of NOPs used, the shadow tracker counts the number
|
|
|
|
// of instruction bytes output since the last stackmap. Only if there are too
|
|
|
|
// few instruction bytes to cover the shadow are NOPs used for padding.
|
|
|
|
class StackMapShadowTracker {
|
|
|
|
public:
|
2016-04-20 02:48:16 +08:00
|
|
|
void startFunction(MachineFunction &MF) {
|
|
|
|
this->MF = &MF;
|
|
|
|
}
|
2016-04-19 13:24:47 +08:00
|
|
|
void count(MCInst &Inst, const MCSubtargetInfo &STI,
|
|
|
|
MCCodeEmitter *CodeEmitter);
|
2014-07-25 10:29:19 +08:00
|
|
|
|
|
|
|
// Called to signal the start of a shadow of RequiredSize bytes.
|
2014-07-25 04:40:55 +08:00
|
|
|
void reset(unsigned RequiredSize) {
|
|
|
|
RequiredShadowSize = RequiredSize;
|
|
|
|
CurrentShadowSize = 0;
|
2014-07-25 10:29:19 +08:00
|
|
|
InShadow = true;
|
2014-07-25 04:40:55 +08:00
|
|
|
}
|
2014-07-25 10:29:19 +08:00
|
|
|
|
|
|
|
// Called before every stackmap/patchpoint, and at the end of basic blocks,
|
|
|
|
// to emit any necessary padding-NOPs.
|
2014-07-25 04:40:55 +08:00
|
|
|
void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI);
|
|
|
|
private:
|
2015-02-20 16:01:55 +08:00
|
|
|
const MachineFunction *MF;
|
2016-04-20 02:48:16 +08:00
|
|
|
bool InShadow = false;
|
2014-07-25 10:29:19 +08:00
|
|
|
|
|
|
|
// RequiredShadowSize holds the length of the shadow specified in the most
|
|
|
|
// recently encountered STACKMAP instruction.
|
|
|
|
// CurrentShadowSize counts the number of bytes encoded since the most
|
|
|
|
// recently encountered STACKMAP, stopping when that number is greater than
|
|
|
|
// or equal to RequiredShadowSize.
|
2016-04-20 02:48:16 +08:00
|
|
|
unsigned RequiredShadowSize = 0, CurrentShadowSize = 0;
|
2014-07-25 04:40:55 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
StackMapShadowTracker SMShadowTracker;
|
|
|
|
|
|
|
|
// All instructions emitted by the X86AsmPrinter should use this helper
|
|
|
|
// method.
|
|
|
|
//
|
|
|
|
// This helper function invokes the SMShadowTracker on each instruction before
|
|
|
|
// outputting it to the OutStream. This allows the shadow tracker to minimise
|
|
|
|
// the number of NOPs used for stackmap padding.
|
|
|
|
void EmitAndCountInstruction(MCInst &Inst);
|
|
|
|
void LowerSTACKMAP(const MachineInstr &MI);
|
2015-04-22 14:02:31 +08:00
|
|
|
void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
|
2015-05-07 07:53:26 +08:00
|
|
|
void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
|
2017-02-08 03:19:49 +08:00
|
|
|
void LowerFAULTING_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
|
2016-04-19 13:24:47 +08:00
|
|
|
void LowerPATCHABLE_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
|
2014-07-25 04:40:55 +08:00
|
|
|
|
|
|
|
void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI);
|
|
|
|
|
XRay: Add entry and exit sleds
Summary:
In this patch we implement the following parts of XRay:
- Supporting a function attribute named 'function-instrument' which currently only supports 'xray-always'. We should be able to use this attribute for other instrumentation approaches.
- Supporting a function attribute named 'xray-instruction-threshold' used to determine whether a function is instrumented with a minimum number of instructions (IR instruction counts).
- X86-specific nop sleds as described in the white paper.
- A machine function pass that adds the different instrumentation marker instructions at a very late stage.
- A way of identifying which return opcode is considered "normal" for each architecture.
There are some caveats here:
1) We don't handle PATCHABLE_RET in platforms other than x86_64 yet -- this means if IR used PATCHABLE_RET directly instead of a normal ret, instruction lowering for that platform might do the wrong thing. We think this should be handled at instruction selection time to by default be unpacked for platforms where XRay is not availble yet.
2) The generated section for X86 is different from what is described from the white paper for the sole reason that LLVM allows us to do this neatly. We're taking the opportunity to deviate from the white paper from this perspective to allow us to get richer information from the runtime library.
Reviewers: sanjoy, eugenis, kcc, pcc, echristo, rnk
Subscribers: niravd, majnemer, atrick, rnk, emaste, bmakam, mcrosier, mehdi_amini, llvm-commits
Differential Revision: http://reviews.llvm.org/D19904
llvm-svn: 275367
2016-07-14 12:06:33 +08:00
|
|
|
// XRay-specific lowering for X86.
|
|
|
|
void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
|
|
|
|
X86MCInstLower &MCIL);
|
|
|
|
void LowerPATCHABLE_RET(const MachineInstr &MI, X86MCInstLower &MCIL);
|
|
|
|
void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
|
[XRay] Custom event logging intrinsic
This patch introduces an LLVM intrinsic and a target opcode for custom event
logging in XRay. Initially, its use case will be to allow users of XRay to log
some type of string ("poor man's printf"). The target opcode compiles to a noop
sled large enough to enable calling through to a runtime-determined relative
function call. At runtime, when X-Ray is enabled, the sled is replaced by
compiler-rt with a trampoline to the logic for creating the custom log entries.
Future patches will implement the compiler-rt parts and clang-side support for
emitting the IR corresponding to this intrinsic.
Reviewers: timshen, dberris
Subscribers: igorb, pelikan, rSerge, timshen, echristo, dberris, llvm-commits
Differential Revision: https://reviews.llvm.org/D27503
llvm-svn: 302405
2017-05-08 13:45:21 +08:00
|
|
|
void LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
|
XRay: Add entry and exit sleds
Summary:
In this patch we implement the following parts of XRay:
- Supporting a function attribute named 'function-instrument' which currently only supports 'xray-always'. We should be able to use this attribute for other instrumentation approaches.
- Supporting a function attribute named 'xray-instruction-threshold' used to determine whether a function is instrumented with a minimum number of instructions (IR instruction counts).
- X86-specific nop sleds as described in the white paper.
- A machine function pass that adds the different instrumentation marker instructions at a very late stage.
- A way of identifying which return opcode is considered "normal" for each architecture.
There are some caveats here:
1) We don't handle PATCHABLE_RET in platforms other than x86_64 yet -- this means if IR used PATCHABLE_RET directly instead of a normal ret, instruction lowering for that platform might do the wrong thing. We think this should be handled at instruction selection time to by default be unpacked for platforms where XRay is not availble yet.
2) The generated section for X86 is different from what is described from the white paper for the sole reason that LLVM allows us to do this neatly. We're taking the opportunity to deviate from the white paper from this perspective to allow us to get richer information from the runtime library.
Reviewers: sanjoy, eugenis, kcc, pcc, echristo, rnk
Subscribers: niravd, majnemer, atrick, rnk, emaste, bmakam, mcrosier, mehdi_amini, llvm-commits
Differential Revision: http://reviews.llvm.org/D19904
llvm-svn: 275367
2016-07-14 12:06:33 +08:00
|
|
|
|
2017-02-01 01:00:27 +08:00
|
|
|
void LowerFENTRY_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
|
|
|
|
|
XRay: Add entry and exit sleds
Summary:
In this patch we implement the following parts of XRay:
- Supporting a function attribute named 'function-instrument' which currently only supports 'xray-always'. We should be able to use this attribute for other instrumentation approaches.
- Supporting a function attribute named 'xray-instruction-threshold' used to determine whether a function is instrumented with a minimum number of instructions (IR instruction counts).
- X86-specific nop sleds as described in the white paper.
- A machine function pass that adds the different instrumentation marker instructions at a very late stage.
- A way of identifying which return opcode is considered "normal" for each architecture.
There are some caveats here:
1) We don't handle PATCHABLE_RET in platforms other than x86_64 yet -- this means if IR used PATCHABLE_RET directly instead of a normal ret, instruction lowering for that platform might do the wrong thing. We think this should be handled at instruction selection time to by default be unpacked for platforms where XRay is not availble yet.
2) The generated section for X86 is different from what is described from the white paper for the sole reason that LLVM allows us to do this neatly. We're taking the opportunity to deviate from the white paper from this perspective to allow us to get richer information from the runtime library.
Reviewers: sanjoy, eugenis, kcc, pcc, echristo, rnk
Subscribers: niravd, majnemer, atrick, rnk, emaste, bmakam, mcrosier, mehdi_amini, llvm-commits
Differential Revision: http://reviews.llvm.org/D19904
llvm-svn: 275367
2016-07-14 12:06:33 +08:00
|
|
|
// Helper function that emits the XRay sleds we've collected for a particular
|
|
|
|
// function.
|
|
|
|
void EmitXRayTable();
|
|
|
|
|
[codeview] Implement FPO data assembler directives
Summary:
This adds a set of new directives that describe 32-bit x86 prologues.
The directives are limited and do not expose the full complexity of
codeview FPO data. They are merely a convenience for the compiler to
generate more readable assembly so we don't need to generate tons of
labels in CodeGen. If our prologue emission changes in the future, we
can change the set of available directives to suit our needs. These are
modelled after the .seh_ directives, which use a different format that
interacts with exception handling.
The directives are:
.cv_fpo_proc _foo
.cv_fpo_pushreg ebp/ebx/etc
.cv_fpo_setframe ebp/esi/etc
.cv_fpo_stackalloc 200
.cv_fpo_endprologue
.cv_fpo_endproc
.cv_fpo_data _foo
I tried to follow the implementation of ARM EHABI CFI directives by
sinking most directives out of MCStreamer and into X86TargetStreamer.
This helps avoid polluting non-X86 code with WinCOFF specific logic.
I used cdb to confirm that this can show locals in parent CSRs in a few
cases, most importantly the one where we use ESI as a frame pointer,
i.e. the one in http://crbug.com/756153#c28
Once we have cdb integration in debuginfo-tests, we can add integration
tests there.
Reviewers: majnemer, hans
Subscribers: aemerson, mgorny, kristof.beyls, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D38776
llvm-svn: 315513
2017-10-12 05:24:33 +08:00
|
|
|
// Choose between emitting .seh_ directives and .cv_fpo_ directives.
|
|
|
|
void EmitSEHInstruction(const MachineInstr *MI);
|
|
|
|
|
XRay: Add entry and exit sleds
Summary:
In this patch we implement the following parts of XRay:
- Supporting a function attribute named 'function-instrument' which currently only supports 'xray-always'. We should be able to use this attribute for other instrumentation approaches.
- Supporting a function attribute named 'xray-instruction-threshold' used to determine whether a function is instrumented with a minimum number of instructions (IR instruction counts).
- X86-specific nop sleds as described in the white paper.
- A machine function pass that adds the different instrumentation marker instructions at a very late stage.
- A way of identifying which return opcode is considered "normal" for each architecture.
There are some caveats here:
1) We don't handle PATCHABLE_RET in platforms other than x86_64 yet -- this means if IR used PATCHABLE_RET directly instead of a normal ret, instruction lowering for that platform might do the wrong thing. We think this should be handled at instruction selection time to by default be unpacked for platforms where XRay is not availble yet.
2) The generated section for X86 is different from what is described from the white paper for the sole reason that LLVM allows us to do this neatly. We're taking the opportunity to deviate from the white paper from this perspective to allow us to get richer information from the runtime library.
Reviewers: sanjoy, eugenis, kcc, pcc, echristo, rnk
Subscribers: niravd, majnemer, atrick, rnk, emaste, bmakam, mcrosier, mehdi_amini, llvm-commits
Differential Revision: http://reviews.llvm.org/D19904
llvm-svn: 275367
2016-07-14 12:06:33 +08:00
|
|
|
public:
|
|
|
|
explicit X86AsmPrinter(TargetMachine &TM,
|
|
|
|
std::unique_ptr<MCStreamer> Streamer)
|
|
|
|
: AsmPrinter(TM, std::move(Streamer)), SM(*this), FM(*this) {}
|
2005-07-02 06:44:09 +08:00
|
|
|
|
2016-10-01 10:56:57 +08:00
|
|
|
StringRef getPassName() const override {
|
2016-11-11 02:39:31 +08:00
|
|
|
return "X86 Assembly Printer";
|
2005-07-02 06:44:09 +08:00
|
|
|
}
|
2012-08-02 02:39:17 +08:00
|
|
|
|
2009-09-13 04:34:57 +08:00
|
|
|
const X86Subtarget &getSubtarget() const { return *Subtarget; }
|
2005-07-02 06:44:09 +08:00
|
|
|
|
2014-03-10 13:29:18 +08:00
|
|
|
void EmitStartOfAsmFile(Module &M) override;
|
2010-03-13 10:10:00 +08:00
|
|
|
|
2014-03-10 13:29:18 +08:00
|
|
|
void EmitEndOfAsmFile(Module &M) override;
|
2012-08-02 02:39:17 +08:00
|
|
|
|
2014-03-10 13:29:18 +08:00
|
|
|
void EmitInstruction(const MachineInstr *MI) override;
|
2012-08-02 02:39:17 +08:00
|
|
|
|
2014-07-25 04:40:55 +08:00
|
|
|
void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override {
|
2015-04-25 03:11:51 +08:00
|
|
|
SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
|
2014-07-25 04:40:55 +08:00
|
|
|
}
|
|
|
|
|
2014-03-10 13:29:18 +08:00
|
|
|
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
|
|
|
unsigned AsmVariant, const char *ExtraCode,
|
|
|
|
raw_ostream &OS) override;
|
|
|
|
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
|
|
|
unsigned AsmVariant, const char *ExtraCode,
|
|
|
|
raw_ostream &OS) override;
|
2012-10-09 11:50:37 +08:00
|
|
|
|
2014-07-15 06:57:27 +08:00
|
|
|
/// \brief Return the symbol for the specified constant pool entry.
|
|
|
|
MCSymbol *GetCPISymbol(unsigned CPID) const override;
|
|
|
|
|
2014-09-17 17:25:36 +08:00
|
|
|
bool doInitialization(Module &M) override {
|
|
|
|
SMShadowTracker.reset(0);
|
|
|
|
SM.reset();
|
|
|
|
return AsmPrinter::doInitialization(M);
|
|
|
|
}
|
|
|
|
|
2014-03-10 13:29:18 +08:00
|
|
|
bool runOnMachineFunction(MachineFunction &F) override;
|
[codeview] Implement FPO data assembler directives
Summary:
This adds a set of new directives that describe 32-bit x86 prologues.
The directives are limited and do not expose the full complexity of
codeview FPO data. They are merely a convenience for the compiler to
generate more readable assembly so we don't need to generate tons of
labels in CodeGen. If our prologue emission changes in the future, we
can change the set of available directives to suit our needs. These are
modelled after the .seh_ directives, which use a different format that
interacts with exception handling.
The directives are:
.cv_fpo_proc _foo
.cv_fpo_pushreg ebp/ebx/etc
.cv_fpo_setframe ebp/esi/etc
.cv_fpo_stackalloc 200
.cv_fpo_endprologue
.cv_fpo_endproc
.cv_fpo_data _foo
I tried to follow the implementation of ARM EHABI CFI directives by
sinking most directives out of MCStreamer and into X86TargetStreamer.
This helps avoid polluting non-X86 code with WinCOFF specific logic.
I used cdb to confirm that this can show locals in parent CSRs in a few
cases, most importantly the one where we use ESI as a frame pointer,
i.e. the one in http://crbug.com/756153#c28
Once we have cdb integration in debuginfo-tests, we can add integration
tests there.
Reviewers: majnemer, hans
Subscribers: aemerson, mgorny, kristof.beyls, llvm-commits, hiraditya
Differential Revision: https://reviews.llvm.org/D38776
llvm-svn: 315513
2017-10-12 05:24:33 +08:00
|
|
|
void EmitFunctionBodyStart() override;
|
|
|
|
void EmitFunctionBodyEnd() override;
|
2005-07-02 06:44:09 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // end namespace llvm
|
|
|
|
|
|
|
|
#endif
|