36 struct InstrumentationOptions {
42 bool HandleAllReturns;
70 InstrumentationOptions);
82 InstrumentationOptions);
87 void XRayInstrumentation::replaceRetWithPatchableRet(
89 InstrumentationOptions
op) {
93 for (
auto &MBB : MF) {
94 for (
auto &
T : MBB.terminators()) {
100 Opc = TargetOpcode::PATCHABLE_RET;
105 Opc = TargetOpcode::PATCHABLE_TAIL_CALL;
108 auto MIB =
BuildMI(MBB,
T,
T.getDebugLoc(), TII->
get(Opc))
109 .addImm(
T.getOpcode());
110 for (
auto &MO :
T.operands())
114 MF.eraseCallSiteInfo(&
T);
119 for (
auto &
I : Terminators)
120 I->eraseFromParent();
123 void XRayInstrumentation::prependRetWithPatchableExit(
125 InstrumentationOptions op) {
127 for (
auto &
T : MBB.terminators()) {
131 Opc = TargetOpcode::PATCHABLE_FUNCTION_EXIT;
134 Opc = TargetOpcode::PATCHABLE_TAIL_CALL;
146 auto InstrAttr =
F.getFnAttribute(
"function-instrument");
148 InstrAttr.isStringAttribute() &&
149 InstrAttr.getValueAsString() ==
"xray-always";
150 Attribute Attr =
F.getFnAttribute(
"xray-instruction-threshold");
151 unsigned XRayThreshold = 0;
152 if (!AlwaysInstrument) {
160 for (
const auto &MBB : MF)
161 MICount += MBB.size();
164 auto *MDT = getAnalysisIfAvailable<MachineDominatorTree>();
172 auto *MLI = getAnalysisIfAvailable<MachineLoopInfo>();
175 ComputedMLI.
getBase().analyze(MDT->getBase());
182 if (MLI->empty() && MICount < XRayThreshold)
193 auto *TII = MF.getSubtarget().getInstrInfo();
194 auto &FirstMBB = *MBI;
195 auto &FirstMI = *FirstMBB.begin();
197 if (!MF.getSubtarget().isXRaySupported()) {
198 FirstMI.emitError(
"An attempt to perform XRay instrumentation for an" 199 " unsupported target.");
205 BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(),
206 TII->
get(TargetOpcode::PATCHABLE_FUNCTION_ENTER));
208 switch (MF.getTarget().getTargetTriple().getArch()) {
209 case Triple::ArchType::arm:
210 case Triple::ArchType::thumb:
211 case Triple::ArchType::aarch64:
212 case Triple::ArchType::mips:
213 case Triple::ArchType::mipsel:
214 case Triple::ArchType::mips64:
215 case Triple::ArchType::mips64el: {
217 InstrumentationOptions
op;
218 op.HandleTailcall =
false;
219 op.HandleAllReturns =
true;
220 prependRetWithPatchableExit(MF, TII, op);
223 case Triple::ArchType::ppc64le: {
225 InstrumentationOptions
op;
226 op.HandleTailcall =
false;
227 op.HandleAllReturns =
true;
228 replaceRetWithPatchableRet(MF, TII, op);
234 InstrumentationOptions
op;
235 op.HandleTailcall =
true;
236 op.HandleAllReturns =
false;
237 replaceRetWithPatchableRet(MF, TII, op);
247 "Insert XRay ops",
false,
false)
const MachineInstrBuilder & add(const MachineOperand &MO) const
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
void push_back(const T &Elt)
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
const HexagonInstrInfo * TII
This file contains the simple types necessary to represent the attributes associated with functions a...
No attributes have been set.
char & XRayInstrumentationID
This pass inserts the XRay instrumentation sleds if they are supported by the target platform...
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.
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Represent the analysis usage information of a pass.
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
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 setPreservesCFG()
This function should be called by the pass, iff they do not:
virtual bool isTailCall(const MachineInstr &Inst) const
Determines whether Inst is a tail call instruction.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
unsigned getReturnOpcode() const
INITIALIZE_PASS_BEGIN(XRayInstrumentation, "xray-instrumentation", "Insert XRay ops", false, false) INITIALIZE_PASS_END(XRayInstrumentation
StringRef getValueAsString() const
Return the attribute's value as a string.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
LoopInfoBase< MachineBasicBlock, MachineLoop > & getBase()