61 void XRayInstrumentation::replaceRetWithPatchableRet(
MachineFunction &MF,
67 for (
auto &
MBB : MF) {
73 Opc = TargetOpcode::PATCHABLE_RET;
78 Opc = TargetOpcode::PATCHABLE_TAIL_CALL;
82 .addImm(
T.getOpcode());
83 for (
auto &MO :
T.operands())
90 for (
auto &
I : Terminators)
94 void XRayInstrumentation::prependRetWithPatchableExit(
MachineFunction &MF,
97 for (
auto &
MBB : MF) {
101 Opc = TargetOpcode::PATCHABLE_FUNCTION_EXIT;
104 Opc = TargetOpcode::PATCHABLE_TAIL_CALL;
117 auto InstrAttr =
F.getFnAttribute(
"function-instrument");
119 InstrAttr.isStringAttribute() &&
120 InstrAttr.getValueAsString() ==
"xray-always";
121 Attribute Attr =
F.getFnAttribute(
"xray-instruction-threshold");
122 unsigned XRayThreshold = 0;
123 if (!AlwaysInstrument) {
128 if (
F.size() < XRayThreshold)
140 auto &FirstMBB = *MBI;
141 auto &FirstMI = *FirstMBB.begin();
144 FirstMI.emitError(
"An attempt to perform XRay instrumentation for an"
145 " unsupported target.");
153 BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(),
154 TII->
get(TargetOpcode::PATCHABLE_FUNCTION_ENTER));
157 case Triple::ArchType::arm:
158 case Triple::ArchType::thumb:
159 case Triple::ArchType::aarch64:
161 prependRetWithPatchableExit(MF, TII);
166 replaceRetWithPatchableRet(MF, TII);
174 INITIALIZE_PASS(XRayInstrumentation,
"xray-instrumentation",
"Insert XRay ops",
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
void push_back(const T &Elt)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
const Triple & getTargetTriple() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
iterator_range< iterator > terminators()
No attributes have been set.
char & XRayInstrumentationID
This pass inserts the XRay instrumentation sleds if they are supported by the target platform...
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
virtual bool isXRaySupported() const
TargetInstrInfo - Interface to description of machine instruction set.
void initializeXRayInstrumentationPass(PassRegistry &)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
virtual bool isTailCall(const MachineInstr &Inst) const
Determines whether |Inst| is a tail call instruction.
unsigned getReturnOpcode() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
StringRef getValueAsString() const
Return the attribute's value as a string.
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...