1//===- bolt/Core/MCPlus.h - Helpers for MCPlus instructions -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains declarations for helper functions for adding annotations
10// to MCInst objects.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef BOLT_CORE_MCPLUS_H
15#define BOLT_CORE_MCPLUS_H
16
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
19#include <vector>
20
21namespace llvm {
22namespace bolt {
23
24// NOTE: using SmallVector for instruction list results in a memory regression.
25using InstructionListType = std::vector<MCInst>;
26
27namespace MCPlus {
28
29/// This type represents C++ EH info for a callsite. The symbol is the landing
30/// pad and the uint64_t represents the action.
31using MCLandingPad = std::pair<const MCSymbol *, uint64_t>;
32
33/// An extension to MCInst is provided via extra operands, i.e. operands that
34/// are not used in the instruction assembly. Any kind of metadata can be
35/// attached to MCInst with this "annotation" extension using MCPlusBuilder
36/// interface.
37//
38/// The first extra operand must be of type kInst with an empty (nullptr)
39/// value. The kInst operand type is unused on most non-VLIW architectures.
40/// We use it to mark the beginning of annotations operands. The rest of the
41/// operands are of Immediate type with annotation info encoded into the value
42/// of the immediate.
43///
44/// There are 2 distinct groups of annotations. The first group is a first-class
45/// annotation that affects semantics of the instruction, such as an
46/// exception-handling or jump table information. The second group contains
47/// information that is supplement, and could be discarded without affecting
48/// correctness of the program. Debugging information, and profile information
49/// belong to the second group.
50///
51/// Note: some optimization/transformation passes could use generic annotations
52/// inside the pass and remove these annotations after the pass. In this
53/// case, the internal state saved with annotations could affect the
54/// correctness.
55///
56/// For the first group, we use a reserved annotation index. Operands in
57/// the first groups store a value of an annotation in the immediate field
58/// of their corresponding operand.
59///
60/// Annotations in the second group could be addressed either by name, or by
61/// by index which could be queried by providing the name.
62class MCAnnotation {
63public:
64 enum Kind {
65 kEHLandingPad, /// Exception handling landing pad.
66 kEHAction, /// Action for exception handler.
67 kGnuArgsSize, /// GNU args size.
68 kJumpTable, /// Jump Table.
69 kTailCall, /// Tail call.
70 kConditionalTailCall, /// CTC.
71 kOffset, /// Offset in the function.
72 kLabel, /// MCSymbol pointing to this instruction.
73 kSize, /// Size of the instruction.
74 kDynamicBranch, /// Jit instruction patched at runtime.
75 kGeneric /// First generic annotation.
76 };
77
78 virtual void print(raw_ostream &OS) const = 0;
79 virtual bool equals(const MCAnnotation &) const = 0;
80 virtual ~MCAnnotation() {}
81
82protected:
83 MCAnnotation() {}
84
85private:
86 // noncopyable
87 MCAnnotation(const MCAnnotation &Other) = delete;
88 MCAnnotation &operator=(const MCAnnotation &Other) = delete;
89};
90
91/// Instances of this class represent a simple annotation with a
92/// specific value type.
93/// Note that if ValueType contains any heap allocated memory, it will
94/// only be freed if the annotation is removed with the
95/// MCPlusBuilder::removeAnnotation method. This is because all
96/// annotations are arena allocated.
97template <typename ValueType> class MCSimpleAnnotation : public MCAnnotation {
98public:
99 ValueType &getValue() { return Value; }
100 bool equals(const MCAnnotation &Other) const override {
101 return Value == static_cast<const MCSimpleAnnotation &>(Other).Value;
102 }
103 explicit MCSimpleAnnotation(const ValueType &Val) : Value(Val) {}
104
105 void print(raw_ostream &OS) const override { OS << Value; }
106
107private:
108 ValueType Value;
109};
110
111/// Return a number of operands in \Inst excluding operands representing
112/// annotations.
113inline unsigned getNumPrimeOperands(const MCInst &Inst) {
114 for (signed I = Inst.getNumOperands() - 1; I >= 0; --I) {
115 if (Inst.getOperand(i: I).isInst())
116 return I;
117 if (!Inst.getOperand(i: I).isImm())
118 return Inst.getNumOperands();
119 }
120 return Inst.getNumOperands();
121}
122
123/// Return iterator range of operands excluding operands representing
124/// annotations.
125inline iterator_range<MCInst::iterator> primeOperands(MCInst &Inst) {
126 return iterator_range<MCInst::iterator>(
127 Inst.begin(), Inst.begin() + getNumPrimeOperands(Inst));
128}
129
130inline iterator_range<MCInst::const_iterator>
131primeOperands(const MCInst &Inst) {
132 return iterator_range<MCInst::const_iterator>(
133 Inst.begin(), Inst.begin() + getNumPrimeOperands(Inst));
134}
135
136} // namespace MCPlus
137
138} // namespace bolt
139} // namespace llvm
140
141#endif
142

source code of bolt/include/bolt/Core/MCPlus.h