1249259Sdim//===---- llvm/MDBuilder.h - Builder for LLVM metadata ----------*- C++ -*-===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file defines the MDBuilder class, which is used as a convenient way to 11249259Sdim// create LLVM metadata with a consistent and simplified interface. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#ifndef LLVM_IR_MDBUILDER_H 16249259Sdim#define LLVM_IR_MDBUILDER_H 17249259Sdim 18249259Sdim#include "llvm/IR/Constants.h" 19249259Sdim#include "llvm/IR/DerivedTypes.h" 20249259Sdim#include "llvm/IR/Metadata.h" 21249259Sdim 22249259Sdimnamespace llvm { 23249259Sdim 24249259Sdimclass APInt; 25249259Sdimclass LLVMContext; 26249259Sdim 27249259Sdimclass MDBuilder { 28249259Sdim LLVMContext &Context; 29249259Sdim 30249259Sdimpublic: 31249259Sdim MDBuilder(LLVMContext &context) : Context(context) {} 32249259Sdim 33249259Sdim /// \brief Return the given string as metadata. 34249259Sdim MDString *createString(StringRef Str) { 35249259Sdim return MDString::get(Context, Str); 36249259Sdim } 37249259Sdim 38249259Sdim //===------------------------------------------------------------------===// 39249259Sdim // FPMath metadata. 40249259Sdim //===------------------------------------------------------------------===// 41249259Sdim 42249259Sdim /// \brief Return metadata with the given settings. The special value 0.0 43249259Sdim /// for the Accuracy parameter indicates the default (maximal precision) 44249259Sdim /// setting. 45249259Sdim MDNode *createFPMath(float Accuracy) { 46249259Sdim if (Accuracy == 0.0) 47249259Sdim return 0; 48249259Sdim assert(Accuracy > 0.0 && "Invalid fpmath accuracy!"); 49249259Sdim Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy); 50249259Sdim return MDNode::get(Context, Op); 51249259Sdim } 52249259Sdim 53249259Sdim //===------------------------------------------------------------------===// 54249259Sdim // Prof metadata. 55249259Sdim //===------------------------------------------------------------------===// 56249259Sdim 57249259Sdim /// \brief Return metadata containing two branch weights. 58249259Sdim MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight) { 59249259Sdim uint32_t Weights[] = { TrueWeight, FalseWeight }; 60249259Sdim return createBranchWeights(Weights); 61249259Sdim } 62249259Sdim 63249259Sdim /// \brief Return metadata containing a number of branch weights. 64249259Sdim MDNode *createBranchWeights(ArrayRef<uint32_t> Weights) { 65249259Sdim assert(Weights.size() >= 2 && "Need at least two branch weights!"); 66249259Sdim 67249259Sdim SmallVector<Value *, 4> Vals(Weights.size()+1); 68249259Sdim Vals[0] = createString("branch_weights"); 69249259Sdim 70249259Sdim Type *Int32Ty = Type::getInt32Ty(Context); 71249259Sdim for (unsigned i = 0, e = Weights.size(); i != e; ++i) 72249259Sdim Vals[i+1] = ConstantInt::get(Int32Ty, Weights[i]); 73249259Sdim 74249259Sdim return MDNode::get(Context, Vals); 75249259Sdim } 76249259Sdim 77249259Sdim //===------------------------------------------------------------------===// 78249259Sdim // Range metadata. 79249259Sdim //===------------------------------------------------------------------===// 80249259Sdim 81249259Sdim /// \brief Return metadata describing the range [Lo, Hi). 82249259Sdim MDNode *createRange(const APInt &Lo, const APInt &Hi) { 83249259Sdim assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!"); 84249259Sdim // If the range is everything then it is useless. 85249259Sdim if (Hi == Lo) 86249259Sdim return 0; 87249259Sdim 88249259Sdim // Return the range [Lo, Hi). 89249259Sdim Type *Ty = IntegerType::get(Context, Lo.getBitWidth()); 90249259Sdim Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) }; 91249259Sdim return MDNode::get(Context, Range); 92249259Sdim } 93249259Sdim 94249259Sdim 95249259Sdim //===------------------------------------------------------------------===// 96249259Sdim // TBAA metadata. 97249259Sdim //===------------------------------------------------------------------===// 98249259Sdim 99249259Sdim /// \brief Return metadata appropriate for a TBAA root node. Each returned 100249259Sdim /// node is distinct from all other metadata and will never be identified 101249259Sdim /// (uniqued) with anything else. 102249259Sdim MDNode *createAnonymousTBAARoot() { 103249259Sdim // To ensure uniqueness the root node is self-referential. 104249259Sdim MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>()); 105249259Sdim MDNode *Root = MDNode::get(Context, Dummy); 106249259Sdim // At this point we have 107249259Sdim // !0 = metadata !{} <- dummy 108249259Sdim // !1 = metadata !{metadata !0} <- root 109249259Sdim // Replace the dummy operand with the root node itself and delete the dummy. 110249259Sdim Root->replaceOperandWith(0, Root); 111249259Sdim MDNode::deleteTemporary(Dummy); 112249259Sdim // We now have 113249259Sdim // !1 = metadata !{metadata !1} <- self-referential root 114249259Sdim return Root; 115249259Sdim } 116249259Sdim 117249259Sdim /// \brief Return metadata appropriate for a TBAA root node with the given 118249259Sdim /// name. This may be identified (uniqued) with other roots with the same 119249259Sdim /// name. 120249259Sdim MDNode *createTBAARoot(StringRef Name) { 121249259Sdim return MDNode::get(Context, createString(Name)); 122249259Sdim } 123249259Sdim 124249259Sdim /// \brief Return metadata for a non-root TBAA node with the given name, 125249259Sdim /// parent in the TBAA tree, and value for 'pointsToConstantMemory'. 126249259Sdim MDNode *createTBAANode(StringRef Name, MDNode *Parent, 127249259Sdim bool isConstant = false) { 128249259Sdim if (isConstant) { 129249259Sdim Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1); 130249259Sdim Value *Ops[3] = { createString(Name), Parent, Flags }; 131249259Sdim return MDNode::get(Context, Ops); 132249259Sdim } else { 133249259Sdim Value *Ops[2] = { createString(Name), Parent }; 134249259Sdim return MDNode::get(Context, Ops); 135249259Sdim } 136249259Sdim } 137249259Sdim 138249259Sdim struct TBAAStructField { 139249259Sdim uint64_t Offset; 140249259Sdim uint64_t Size; 141249259Sdim MDNode *TBAA; 142249259Sdim TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) : 143249259Sdim Offset(Offset), Size(Size), TBAA(TBAA) {} 144249259Sdim }; 145249259Sdim 146249259Sdim /// \brief Return metadata for a tbaa.struct node with the given 147249259Sdim /// struct field descriptions. 148249259Sdim MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) { 149249259Sdim SmallVector<Value *, 4> Vals(Fields.size() * 3); 150249259Sdim Type *Int64 = IntegerType::get(Context, 64); 151249259Sdim for (unsigned i = 0, e = Fields.size(); i != e; ++i) { 152249259Sdim Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset); 153249259Sdim Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size); 154249259Sdim Vals[i * 3 + 2] = Fields[i].TBAA; 155249259Sdim } 156249259Sdim return MDNode::get(Context, Vals); 157249259Sdim } 158249259Sdim 159249259Sdim /// \brief Return metadata for a TBAA struct node in the type DAG 160252723Sdim /// with the given name, a list of pairs (offset, field type in the type DAG). 161249259Sdim MDNode *createTBAAStructTypeNode(StringRef Name, 162252723Sdim ArrayRef<std::pair<MDNode*, uint64_t> > Fields) { 163249259Sdim SmallVector<Value *, 4> Ops(Fields.size() * 2 + 1); 164249259Sdim Type *Int64 = IntegerType::get(Context, 64); 165249259Sdim Ops[0] = createString(Name); 166249259Sdim for (unsigned i = 0, e = Fields.size(); i != e; ++i) { 167252723Sdim Ops[i * 2 + 1] = Fields[i].first; 168252723Sdim Ops[i * 2 + 2] = ConstantInt::get(Int64, Fields[i].second); 169249259Sdim } 170249259Sdim return MDNode::get(Context, Ops); 171249259Sdim } 172249259Sdim 173252723Sdim /// \brief Return metadata for a TBAA scalar type node with the 174252723Sdim /// given name, an offset and a parent in the TBAA type DAG. 175252723Sdim MDNode *createTBAAScalarTypeNode(StringRef Name, MDNode *Parent, 176252723Sdim uint64_t Offset = 0) { 177252723Sdim SmallVector<Value *, 4> Ops(3); 178252723Sdim Type *Int64 = IntegerType::get(Context, 64); 179252723Sdim Ops[0] = createString(Name); 180252723Sdim Ops[1] = Parent; 181252723Sdim Ops[2] = ConstantInt::get(Int64, Offset); 182252723Sdim return MDNode::get(Context, Ops); 183252723Sdim } 184252723Sdim 185249259Sdim /// \brief Return metadata for a TBAA tag node with the given 186249259Sdim /// base type, access type and offset relative to the base type. 187249259Sdim MDNode *createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, 188249259Sdim uint64_t Offset) { 189249259Sdim Type *Int64 = IntegerType::get(Context, 64); 190249259Sdim Value *Ops[3] = { BaseType, AccessType, ConstantInt::get(Int64, Offset) }; 191249259Sdim return MDNode::get(Context, Ops); 192249259Sdim } 193249259Sdim 194249259Sdim}; 195249259Sdim 196249259Sdim} // end namespace llvm 197249259Sdim 198249259Sdim#endif 199