xref: /minix3/external/bsd/llvm/dist/llvm/lib/IR/MDBuilder.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc //===---- llvm/MDBuilder.cpp - Builder for LLVM metadata ------------------===//
2*0a6a1f1dSLionel Sambuc //
3*0a6a1f1dSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*0a6a1f1dSLionel Sambuc //
5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details.
7*0a6a1f1dSLionel Sambuc //
8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
9*0a6a1f1dSLionel Sambuc //
10*0a6a1f1dSLionel Sambuc // This file defines the MDBuilder class, which is used as a convenient way to
11*0a6a1f1dSLionel Sambuc // create LLVM metadata with a consistent and simplified interface.
12*0a6a1f1dSLionel Sambuc //
13*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
14*0a6a1f1dSLionel Sambuc 
15*0a6a1f1dSLionel Sambuc #include "llvm/IR/MDBuilder.h"
16*0a6a1f1dSLionel Sambuc #include "llvm/IR/Constants.h"
17*0a6a1f1dSLionel Sambuc #include "llvm/IR/Metadata.h"
18*0a6a1f1dSLionel Sambuc using namespace llvm;
19*0a6a1f1dSLionel Sambuc 
createString(StringRef Str)20*0a6a1f1dSLionel Sambuc MDString *MDBuilder::createString(StringRef Str) {
21*0a6a1f1dSLionel Sambuc   return MDString::get(Context, Str);
22*0a6a1f1dSLionel Sambuc }
23*0a6a1f1dSLionel Sambuc 
createConstant(Constant * C)24*0a6a1f1dSLionel Sambuc ConstantAsMetadata *MDBuilder::createConstant(Constant *C) {
25*0a6a1f1dSLionel Sambuc   return ConstantAsMetadata::get(C);
26*0a6a1f1dSLionel Sambuc }
27*0a6a1f1dSLionel Sambuc 
createFPMath(float Accuracy)28*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createFPMath(float Accuracy) {
29*0a6a1f1dSLionel Sambuc   if (Accuracy == 0.0)
30*0a6a1f1dSLionel Sambuc     return nullptr;
31*0a6a1f1dSLionel Sambuc   assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
32*0a6a1f1dSLionel Sambuc   auto *Op =
33*0a6a1f1dSLionel Sambuc       createConstant(ConstantFP::get(Type::getFloatTy(Context), Accuracy));
34*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, Op);
35*0a6a1f1dSLionel Sambuc }
36*0a6a1f1dSLionel Sambuc 
createBranchWeights(uint32_t TrueWeight,uint32_t FalseWeight)37*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight,
38*0a6a1f1dSLionel Sambuc                                        uint32_t FalseWeight) {
39*0a6a1f1dSLionel Sambuc   uint32_t Weights[] = {TrueWeight, FalseWeight};
40*0a6a1f1dSLionel Sambuc   return createBranchWeights(Weights);
41*0a6a1f1dSLionel Sambuc }
42*0a6a1f1dSLionel Sambuc 
createBranchWeights(ArrayRef<uint32_t> Weights)43*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) {
44*0a6a1f1dSLionel Sambuc   assert(Weights.size() >= 2 && "Need at least two branch weights!");
45*0a6a1f1dSLionel Sambuc 
46*0a6a1f1dSLionel Sambuc   SmallVector<Metadata *, 4> Vals(Weights.size() + 1);
47*0a6a1f1dSLionel Sambuc   Vals[0] = createString("branch_weights");
48*0a6a1f1dSLionel Sambuc 
49*0a6a1f1dSLionel Sambuc   Type *Int32Ty = Type::getInt32Ty(Context);
50*0a6a1f1dSLionel Sambuc   for (unsigned i = 0, e = Weights.size(); i != e; ++i)
51*0a6a1f1dSLionel Sambuc     Vals[i + 1] = createConstant(ConstantInt::get(Int32Ty, Weights[i]));
52*0a6a1f1dSLionel Sambuc 
53*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, Vals);
54*0a6a1f1dSLionel Sambuc }
55*0a6a1f1dSLionel Sambuc 
createRange(const APInt & Lo,const APInt & Hi)56*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) {
57*0a6a1f1dSLionel Sambuc   assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");
58*0a6a1f1dSLionel Sambuc   // If the range is everything then it is useless.
59*0a6a1f1dSLionel Sambuc   if (Hi == Lo)
60*0a6a1f1dSLionel Sambuc     return nullptr;
61*0a6a1f1dSLionel Sambuc 
62*0a6a1f1dSLionel Sambuc   // Return the range [Lo, Hi).
63*0a6a1f1dSLionel Sambuc   Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
64*0a6a1f1dSLionel Sambuc   Metadata *Range[2] = {createConstant(ConstantInt::get(Ty, Lo)),
65*0a6a1f1dSLionel Sambuc                         createConstant(ConstantInt::get(Ty, Hi))};
66*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, Range);
67*0a6a1f1dSLionel Sambuc }
68*0a6a1f1dSLionel Sambuc 
createAnonymousAARoot(StringRef Name,MDNode * Extra)69*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
70*0a6a1f1dSLionel Sambuc   // To ensure uniqueness the root node is self-referential.
71*0a6a1f1dSLionel Sambuc   MDNode *Dummy = MDNode::getTemporary(Context, None);
72*0a6a1f1dSLionel Sambuc 
73*0a6a1f1dSLionel Sambuc   SmallVector<Metadata *, 3> Args(1, Dummy);
74*0a6a1f1dSLionel Sambuc   if (Extra)
75*0a6a1f1dSLionel Sambuc     Args.push_back(Extra);
76*0a6a1f1dSLionel Sambuc   if (!Name.empty())
77*0a6a1f1dSLionel Sambuc     Args.push_back(createString(Name));
78*0a6a1f1dSLionel Sambuc   MDNode *Root = MDNode::get(Context, Args);
79*0a6a1f1dSLionel Sambuc 
80*0a6a1f1dSLionel Sambuc   // At this point we have
81*0a6a1f1dSLionel Sambuc   //   !0 = metadata !{}            <- dummy
82*0a6a1f1dSLionel Sambuc   //   !1 = metadata !{metadata !0} <- root
83*0a6a1f1dSLionel Sambuc   // Replace the dummy operand with the root node itself and delete the dummy.
84*0a6a1f1dSLionel Sambuc   Root->replaceOperandWith(0, Root);
85*0a6a1f1dSLionel Sambuc   MDNode::deleteTemporary(Dummy);
86*0a6a1f1dSLionel Sambuc   // We now have
87*0a6a1f1dSLionel Sambuc   //   !1 = metadata !{metadata !1} <- self-referential root
88*0a6a1f1dSLionel Sambuc   return Root;
89*0a6a1f1dSLionel Sambuc }
90*0a6a1f1dSLionel Sambuc 
createTBAARoot(StringRef Name)91*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createTBAARoot(StringRef Name) {
92*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, createString(Name));
93*0a6a1f1dSLionel Sambuc }
94*0a6a1f1dSLionel Sambuc 
95*0a6a1f1dSLionel Sambuc /// \brief Return metadata for a non-root TBAA node with the given name,
96*0a6a1f1dSLionel Sambuc /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
createTBAANode(StringRef Name,MDNode * Parent,bool isConstant)97*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createTBAANode(StringRef Name, MDNode *Parent,
98*0a6a1f1dSLionel Sambuc                                   bool isConstant) {
99*0a6a1f1dSLionel Sambuc   if (isConstant) {
100*0a6a1f1dSLionel Sambuc     Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
101*0a6a1f1dSLionel Sambuc     Metadata *Ops[3] = {createString(Name), Parent, createConstant(Flags)};
102*0a6a1f1dSLionel Sambuc     return MDNode::get(Context, Ops);
103*0a6a1f1dSLionel Sambuc   } else {
104*0a6a1f1dSLionel Sambuc     Metadata *Ops[2] = {createString(Name), Parent};
105*0a6a1f1dSLionel Sambuc     return MDNode::get(Context, Ops);
106*0a6a1f1dSLionel Sambuc   }
107*0a6a1f1dSLionel Sambuc }
108*0a6a1f1dSLionel Sambuc 
createAliasScopeDomain(StringRef Name)109*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) {
110*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, createString(Name));
111*0a6a1f1dSLionel Sambuc }
112*0a6a1f1dSLionel Sambuc 
createAliasScope(StringRef Name,MDNode * Domain)113*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) {
114*0a6a1f1dSLionel Sambuc   Metadata *Ops[2] = {createString(Name), Domain};
115*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, Ops);
116*0a6a1f1dSLionel Sambuc }
117*0a6a1f1dSLionel Sambuc 
118*0a6a1f1dSLionel Sambuc /// \brief Return metadata for a tbaa.struct node with the given
119*0a6a1f1dSLionel Sambuc /// struct field descriptions.
createTBAAStructNode(ArrayRef<TBAAStructField> Fields)120*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createTBAAStructNode(ArrayRef<TBAAStructField> Fields) {
121*0a6a1f1dSLionel Sambuc   SmallVector<Metadata *, 4> Vals(Fields.size() * 3);
122*0a6a1f1dSLionel Sambuc   Type *Int64 = Type::getInt64Ty(Context);
123*0a6a1f1dSLionel Sambuc   for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
124*0a6a1f1dSLionel Sambuc     Vals[i * 3 + 0] = createConstant(ConstantInt::get(Int64, Fields[i].Offset));
125*0a6a1f1dSLionel Sambuc     Vals[i * 3 + 1] = createConstant(ConstantInt::get(Int64, Fields[i].Size));
126*0a6a1f1dSLionel Sambuc     Vals[i * 3 + 2] = Fields[i].TBAA;
127*0a6a1f1dSLionel Sambuc   }
128*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, Vals);
129*0a6a1f1dSLionel Sambuc }
130*0a6a1f1dSLionel Sambuc 
131*0a6a1f1dSLionel Sambuc /// \brief Return metadata for a TBAA struct node in the type DAG
132*0a6a1f1dSLionel Sambuc /// with the given name, a list of pairs (offset, field type in the type DAG).
createTBAAStructTypeNode(StringRef Name,ArrayRef<std::pair<MDNode *,uint64_t>> Fields)133*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createTBAAStructTypeNode(
134*0a6a1f1dSLionel Sambuc     StringRef Name, ArrayRef<std::pair<MDNode *, uint64_t>> Fields) {
135*0a6a1f1dSLionel Sambuc   SmallVector<Metadata *, 4> Ops(Fields.size() * 2 + 1);
136*0a6a1f1dSLionel Sambuc   Type *Int64 = Type::getInt64Ty(Context);
137*0a6a1f1dSLionel Sambuc   Ops[0] = createString(Name);
138*0a6a1f1dSLionel Sambuc   for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
139*0a6a1f1dSLionel Sambuc     Ops[i * 2 + 1] = Fields[i].first;
140*0a6a1f1dSLionel Sambuc     Ops[i * 2 + 2] = createConstant(ConstantInt::get(Int64, Fields[i].second));
141*0a6a1f1dSLionel Sambuc   }
142*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, Ops);
143*0a6a1f1dSLionel Sambuc }
144*0a6a1f1dSLionel Sambuc 
145*0a6a1f1dSLionel Sambuc /// \brief Return metadata for a TBAA scalar type node with the
146*0a6a1f1dSLionel Sambuc /// given name, an offset and a parent in the TBAA type DAG.
createTBAAScalarTypeNode(StringRef Name,MDNode * Parent,uint64_t Offset)147*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
148*0a6a1f1dSLionel Sambuc                                             uint64_t Offset) {
149*0a6a1f1dSLionel Sambuc   ConstantInt *Off = ConstantInt::get(Type::getInt64Ty(Context), Offset);
150*0a6a1f1dSLionel Sambuc   Metadata *Ops[3] = {createString(Name), Parent, createConstant(Off)};
151*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, Ops);
152*0a6a1f1dSLionel Sambuc }
153*0a6a1f1dSLionel Sambuc 
154*0a6a1f1dSLionel Sambuc /// \brief Return metadata for a TBAA tag node with the given
155*0a6a1f1dSLionel Sambuc /// base type, access type and offset relative to the base type.
createTBAAStructTagNode(MDNode * BaseType,MDNode * AccessType,uint64_t Offset)156*0a6a1f1dSLionel Sambuc MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
157*0a6a1f1dSLionel Sambuc                                            uint64_t Offset) {
158*0a6a1f1dSLionel Sambuc   Type *Int64 = Type::getInt64Ty(Context);
159*0a6a1f1dSLionel Sambuc   Metadata *Ops[3] = {BaseType, AccessType,
160*0a6a1f1dSLionel Sambuc                       createConstant(ConstantInt::get(Int64, Offset))};
161*0a6a1f1dSLionel Sambuc   return MDNode::get(Context, Ops);
162*0a6a1f1dSLionel Sambuc }
163