LLDB build is also broken in multiple places, and not just on MSVC. I'm not sure how to fix some of these. Would you mind fixing them?<br><br><div class="gmail_quote">On Tue Dec 09 2014 at 10:43:10 AM Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com">dexonsmith@apple.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dexonsmith<br>
Date: Tue Dec 9 12:38:53 2014<br>
New Revision: 223802<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=223802&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=223802&view=rev</a><br>
Log:<br>
IR: Split Metadata from Value<br>
<br>
Split `Metadata` away from the `Value` class hierarchy, as part of<br>
PR21532. Assembly and bitcode changes are in the wings, but this is the<br>
bulk of the change for the IR C++ API.<br>
<br>
I have a follow-up patch prepared for `clang`. If this breaks other<br>
sub-projects, I apologize in advance :(. Help me compile it on Darwin<br>
I'll try to fix it. FWIW, the errors should be easy to fix, so it may<br>
be simpler to just fix it yourself.<br>
<br>
This breaks the build for all metadata-related code that's out-of-tree.<br>
Rest assured the transition is mechanical and the compiler should catch<br>
almost all of the problems.<br>
<br>
Here's a quick guide for updating your code:<br>
<br>
- `Metadata` is the root of a class hierarchy with three main classes:<br>
`MDNode`, `MDString`, and `ValueAsMetadata`. It is distinct from<br>
the `Value` class hierarchy. It is typeless -- i.e., instances do<br>
*not* have a `Type`.<br>
<br>
- `MDNode`'s operands are all `Metadata *` (instead of `Value *`).<br>
<br>
- `TrackingVH<MDNode>` and `WeakVH` referring to metadata can be<br>
replaced with `TrackingMDNodeRef` and `TrackingMDRef`, respectively.<br>
<br>
If you're referring solely to resolved `MDNode`s -- post graph<br>
construction -- just use `MDNode*`.<br>
<br>
- `MDNode` (and the rest of `Metadata`) have only limited support for<br>
`replaceAllUsesWith()`.<br>
<br>
As long as an `MDNode` is pointing at a forward declaration -- the<br>
result of `MDNode::getTemporary()` -- it maintains a side map of its<br>
uses and can RAUW itself. Once the forward declarations are fully<br>
resolved RAUW support is dropped on the ground. This means that<br>
uniquing collisions on changing operands cause nodes to become<br>
"distinct". (This already happened fairly commonly, whenever an<br>
operand went to null.)<br>
<br>
If you're constructing complex (non self-reference) `MDNode` cycles,<br>
you need to call `MDNode::resolveCycles()` on each node (or on a<br>
top-level node that somehow references all of the nodes). Also,<br>
don't do that. Metadata cycles (and the RAUW machinery needed to<br>
construct them) are expensive.<br>
<br>
- An `MDNode` can only refer to a `Constant` through a bridge called<br>
`ConstantAsMetadata` (one of the subclasses of `ValueAsMetadata`).<br>
<br>
As a side effect, accessing an operand of an `MDNode` that is known<br>
to be, e.g., `ConstantInt`, takes three steps: first, cast from<br>
`Metadata` to `ConstantAsMetadata`; second, extract the `Constant`;<br>
third, cast down to `ConstantInt`.<br>
<br>
The eventual goal is to introduce `MDInt`/`MDFloat`/etc. and have<br>
metadata schema owners transition away from using `Constant`s when<br>
the type isn't important (and they don't care about referring to<br>
`GlobalValue`s).<br>
<br>
In the meantime, I've added transitional API to the `mdconst`<br>
namespace that matches semantics with the old code, in order to<br>
avoid adding the error-prone three-step equivalent to every call<br>
site. If your old code was:<br>
<br>
MDNode *N = foo();<br>
bar(isa <ConstantInt>(N->getOperand(0)<u></u>));<br>
baz(cast <ConstantInt>(N->getOperand(1)<u></u>));<br>
bak(cast_or_null <ConstantInt>(N->getOperand(2)<u></u>));<br>
bat(dyn_cast <ConstantInt>(N->getOperand(3)<u></u>));<br>
bay(dyn_cast_or_null<<u></u>ConstantInt>(N->getOperand(4))<u></u>);<br>
<br>
you can trivially match its semantics with:<br>
<br>
MDNode *N = foo();<br>
bar(mdconst::hasa <ConstantInt>(N->getOperand(0)<u></u>));<br>
baz(mdconst::extract <ConstantInt>(N->getOperand(1)<u></u>));<br>
bak(mdconst::extract_or_null <ConstantInt>(N->getOperand(2)<u></u>));<br>
bat(mdconst::dyn_extract <ConstantInt>(N->getOperand(3)<u></u>));<br>
bay(mdconst::dyn_extract_or_<u></u>null<ConstantInt>(N-><u></u>getOperand(4)));<br>
<br>
and when you transition your metadata schema to `MDInt`:<br>
<br>
MDNode *N = foo();<br>
bar(isa <MDInt>(N->getOperand(0)));<br>
baz(cast <MDInt>(N->getOperand(1)));<br>
bak(cast_or_null <MDInt>(N->getOperand(2)));<br>
bat(dyn_cast <MDInt>(N->getOperand(3)));<br>
bay(dyn_cast_or_null<MDInt>(N-<u></u>>getOperand(4)));<br>
<br>
- A `CallInst` -- specifically, intrinsic instructions -- can refer to<br>
metadata through a bridge called `MetadataAsValue`. This is a<br>
subclass of `Value` where `getType()->isMetadataTy()`.<br>
<br>
`MetadataAsValue` is the *only* class that can legally refer to a<br>
`LocalAsMetadata`, which is a bridged form of non-`Constant` values<br>
like `Argument` and `Instruction`. It can also refer to any other<br>
`Metadata` subclass.<br>
<br>
(I'll break all your testcases in a follow-up commit, when I propagate<br>
this change to assembly.)<br>
<br>
Added:<br>
llvm/trunk/include/llvm/IR/<u></u>Metadata.def<br>
llvm/trunk/include/llvm/IR/<u></u>MetadataTracking.h<br>
llvm/trunk/include/llvm/IR/<u></u>TrackingMDRef.h<br>
llvm/trunk/lib/IR/<u></u>MetadataTracking.cpp<br>
llvm/trunk/test/Linker/Inputs/<u></u>unique-fwd-decl-order.ll<br>
llvm/trunk/test/Linker/unique-<u></u>fwd-decl-order.ll<br>
Modified:<br>
llvm/trunk/bindings/go/llvm/<u></u>DIBuilderBindings.cpp<br>
llvm/trunk/include/llvm-c/<u></u>Core.h<br>
llvm/trunk/include/llvm/<u></u>CodeGen/LexicalScopes.h<br>
llvm/trunk/include/llvm/<u></u>CodeGen/MachineInstr.h<br>
llvm/trunk/include/llvm/<u></u>CodeGen/MachineModuleInfo.h<br>
llvm/trunk/include/llvm/<u></u>CodeGen/SelectionDAGNodes.h<br>
llvm/trunk/include/llvm/IR/<u></u>DIBuilder.h<br>
llvm/trunk/include/llvm/IR/<u></u>DebugInfo.h<br>
llvm/trunk/include/llvm/IR/<u></u>DebugLoc.h<br>
llvm/trunk/include/llvm/IR/<u></u>IntrinsicInst.h<br>
llvm/trunk/include/llvm/IR/<u></u>MDBuilder.h<br>
llvm/trunk/include/llvm/IR/<u></u>Metadata.h<br>
llvm/trunk/include/llvm/IR/<u></u>Module.h<br>
llvm/trunk/include/llvm/IR/<u></u>TypeFinder.h<br>
llvm/trunk/include/llvm/IR/<u></u>Value.h<br>
llvm/trunk/include/llvm/IR/<u></u>ValueMap.h<br>
llvm/trunk/include/llvm/<u></u>Transforms/Utils/ValueMapper.h<br>
llvm/trunk/lib/Analysis/<u></u>BranchProbabilityInfo.cpp<br>
llvm/trunk/lib/Analysis/<u></u>ScalarEvolution.cpp<br>
llvm/trunk/lib/Analysis/<u></u>TypeBasedAliasAnalysis.cpp<br>
llvm/trunk/lib/Analysis/<u></u>ValueTracking.cpp<br>
llvm/trunk/lib/AsmParser/<u></u>LLParser.cpp<br>
llvm/trunk/lib/AsmParser/<u></u>LLParser.h<br>
llvm/trunk/lib/Bitcode/Reader/<u></u>BitcodeReader.cpp<br>
llvm/trunk/lib/Bitcode/Reader/<u></u>BitcodeReader.h<br>
llvm/trunk/lib/Bitcode/Writer/<u></u>BitcodeWriter.cpp<br>
llvm/trunk/lib/Bitcode/Writer/<u></u>ValueEnumerator.cpp<br>
llvm/trunk/lib/Bitcode/Writer/<u></u>ValueEnumerator.h<br>
llvm/trunk/lib/CodeGen/<u></u>AsmPrinter/<u></u>AsmPrinterInlineAsm.cpp<br>
llvm/trunk/lib/CodeGen/<u></u>AsmPrinter/DwarfUnit.cpp<br>
llvm/trunk/lib/CodeGen/<u></u>CodeGenPrepare.cpp<br>
llvm/trunk/lib/CodeGen/<u></u>MachineInstr.cpp<br>
llvm/trunk/lib/CodeGen/<u></u>SelectionDAG/<u></u>SelectionDAGBuilder.cpp<br>
llvm/trunk/lib/CodeGen/<u></u>StackColoring.cpp<br>
llvm/trunk/lib/CodeGen/<u></u>TargetLoweringObjectFileImpl.<u></u>cpp<br>
llvm/trunk/lib/IR/AsmWriter.<u></u>cpp<br>
llvm/trunk/lib/IR/AutoUpgrade.<u></u>cpp<br>
llvm/trunk/lib/IR/CMakeLists.<u></u>txt<br>
llvm/trunk/lib/IR/Core.cpp<br>
llvm/trunk/lib/IR/DIBuilder.<u></u>cpp<br>
llvm/trunk/lib/IR/DebugInfo.<u></u>cpp<br>
llvm/trunk/lib/IR/DebugLoc.cpp<br>
llvm/trunk/lib/IR/<u></u>DiagnosticInfo.cpp<br>
llvm/trunk/lib/IR/<u></u>Instructions.cpp<br>
llvm/trunk/lib/IR/<u></u>IntrinsicInst.cpp<br>
llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp<br>
llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h<br>
llvm/trunk/lib/IR/MDBuilder.<u></u>cpp<br>
llvm/trunk/lib/IR/Metadata.cpp<br>
llvm/trunk/lib/IR/Module.cpp<br>
llvm/trunk/lib/IR/TypeFinder.<u></u>cpp<br>
llvm/trunk/lib/IR/Value.cpp<br>
llvm/trunk/lib/IR/<u></u>ValueSymbolTable.cpp<br>
llvm/trunk/lib/IR/Verifier.cpp<br>
llvm/trunk/lib/LTO/LTOModule.<u></u>cpp<br>
llvm/trunk/lib/Linker/<u></u>LinkModules.cpp<br>
llvm/trunk/lib/Target/ARM/<u></u>ARMAsmPrinter.cpp<br>
llvm/trunk/lib/Target/NVPTX/<u></u>NVPTXGenericToNVVM.cpp<br>
llvm/trunk/lib/Target/NVPTX/<u></u>NVPTXUtilities.cpp<br>
llvm/trunk/lib/Transforms/IPO/<u></u>StripSymbols.cpp<br>
llvm/trunk/lib/Transforms/<u></u>InstCombine/InstCombineCalls.<u></u>cpp<br>
llvm/trunk/lib/Transforms/<u></u>Instrumentation/<u></u>AddressSanitizer.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Instrumentation/<u></u>SanitizerCoverage.cpp<br>
llvm/trunk/lib/Transforms/<u></u>ObjCARC/ObjCARCOpts.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Scalar/LoopUnrollPass.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Scalar/SROA.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Scalar/ScalarReplAggregates.<u></u>cpp<br>
llvm/trunk/lib/Transforms/<u></u>Utils/AddDiscriminators.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Utils/CloneFunction.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Utils/InlineFunction.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Utils/Local.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Utils/LoopUnrollRuntime.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Utils/PromoteMemoryToRegister.<u></u>cpp<br>
llvm/trunk/lib/Transforms/<u></u>Utils/SimplifyCFG.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Utils/ValueMapper.cpp<br>
llvm/trunk/lib/Transforms/<u></u>Vectorize/LoopVectorize.cpp<br>
llvm/trunk/test/Assembler/<u></u>functionlocal-metadata-<u></u>attachments.ll<br>
llvm/trunk/test/Assembler/<u></u>functionlocal-metadata-<u></u>complex-3.ll<br>
llvm/trunk/test/Feature/<u></u>metadata.ll<br>
llvm/trunk/test/Transforms/<u></u>GlobalOpt/metadata.ll<br>
llvm/trunk/unittests/IR/<u></u>MDBuilderTest.cpp<br>
llvm/trunk/unittests/IR/<u></u>MetadataTest.cpp<br>
<br>
Modified: llvm/trunk/bindings/go/llvm/<u></u>DIBuilderBindings.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/go/llvm/DIBuilderBindings.cpp?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/bindings/<u></u>go/llvm/DIBuilderBindings.cpp?<u></u>rev=223802&r1=223801&r2=<u></u>223802&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/bindings/go/llvm/<u></u>DIBuilderBindings.cpp (original)<br>
+++ llvm/trunk/bindings/go/llvm/<u></u>DIBuilderBindings.cpp Tue Dec 9 12:38:53 2014<br>
@@ -18,10 +18,31 @@<br>
<br>
using namespace llvm;<br>
<br>
+static Metadata *unwrapMetadata(LLVMValueRef VRef) {<br>
+ Value *V = unwrap(VRef);<br>
+ if (!V)<br>
+ return nullptr;<br>
+ if (auto *MD = dyn_cast<MetadataAsValue>(V))<br>
+ return MD->getMetadata();<br>
+ return ValueAsMetadata::get(V);<br>
+}<br>
+<br>
+static SmallVector<Metadata *, 8> unwrapMetadataArray(<u></u>LLVMValueRef *Data,<br>
+ size_t Length) {<br>
+ SmallVector<Metadata *, 8> Elements;<br>
+ for (size_t I = 0; I != Length; ++I)<br>
+ Elements.push_back(<u></u>unwrapMetadata(Data[I]));<br>
+ return Elements;<br>
+}<br>
+<br>
namespace {<br>
template <typename T> T unwrapDI(LLVMValueRef v) {<br>
- return v ? T(unwrap<MDNode>(v)) : T();<br>
+ return T(cast_or_null<MDNode>(<u></u>unwrapMetadata(v)));<br>
+}<br>
}<br>
+<br>
+static LLVMValueRef wrapDI(DIDescriptor N) {<br>
+ return wrap(MetadataAsValue::get(N-><u></u>getContext(), N));<br>
}<br>
<br>
DEFINE_SIMPLE_CONVERSION_<u></u>FUNCTIONS(DIBuilder, LLVMDIBuilderRef)<br>
@@ -47,14 +68,14 @@ LLVMValueRef LLVMDIBuilderCreateCompileU<br>
DIBuilder *D = unwrap(Dref);<br>
DICompileUnit CU = D->createCompileUnit(Lang, File, Dir, Producer, Optimized,<br>
Flags, RuntimeVersion);<br>
- return wrap(CU);<br>
+ return wrapDI(CU);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateFile(<u></u>LLVMDIBuilderRef Dref, const char *File,<br>
const char *Dir) {<br>
DIBuilder *D = unwrap(Dref);<br>
DIFile F = D->createFile(File, Dir);<br>
- return wrap(F);<br>
+ return wrapDI(F);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateLexicalBloc<u></u>k(LLVMDIBuilderRef Dref,<br>
@@ -64,7 +85,7 @@ LLVMValueRef LLVMDIBuilderCreateLexicalB<br>
DIBuilder *D = unwrap(Dref);<br>
DILexicalBlock LB = D->createLexicalBlock(<br>
unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Column);<br>
- return wrap(LB);<br>
+ return wrapDI(LB);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateLexicalBloc<u></u>kFile(LLVMDIBuilderRef Dref,<br>
@@ -74,7 +95,7 @@ LLVMValueRef LLVMDIBuilderCreateLexicalB<br>
DIBuilder *D = unwrap(Dref);<br>
DILexicalBlockFile LBF = D->createLexicalBlockFile(<br>
unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Discriminator);<br>
- return wrap(LBF);<br>
+ return wrapDI(LBF);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateFunction(<br>
@@ -87,7 +108,7 @@ LLVMValueRef LLVMDIBuilderCreateFunction<br>
unwrapDI<DIDescriptor>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),<br>
Line, unwrapDI<DICompositeType>(<u></u>CompositeType), IsLocalToUnit,<br>
IsDefinition, ScopeLine, Flags, IsOptimized, unwrap<Function>(Func));<br>
- return wrap(SP);<br>
+ return wrapDI(SP);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateLocalVariab<u></u>le(<br>
@@ -98,7 +119,7 @@ LLVMValueRef LLVMDIBuilderCreateLocalVar<br>
DIVariable V = D->createLocalVariable(<br>
Tag, unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,<br>
unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo);<br>
- return wrap(V);<br>
+ return wrapDI(V);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateBasicType(<u></u>LLVMDIBuilderRef Dref,<br>
@@ -107,7 +128,7 @@ LLVMValueRef LLVMDIBuilderCreateBasicTyp<br>
unsigned Encoding) {<br>
DIBuilder *D = unwrap(Dref);<br>
DIBasicType T = D->createBasicType(Name, SizeInBits, AlignInBits, Encoding);<br>
- return wrap(T);<br>
+ return wrapDI(T);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreatePointerType<u></u>(LLVMDIBuilderRef Dref,<br>
@@ -118,7 +139,7 @@ LLVMValueRef LLVMDIBuilderCreatePointerT<br>
DIBuilder *D = unwrap(Dref);<br>
DIDerivedType T = D->createPointerType(unwrapDI<<u></u>DIType>(PointeeType),<br>
SizeInBits, AlignInBits, Name);<br>
- return wrap(T);<br>
+ return wrapDI(T);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateSubroutineT<u></u>ype(LLVMDIBuilderRef Dref,<br>
@@ -127,7 +148,7 @@ LLVMValueRef LLVMDIBuilderCreateSubrouti<br>
DIBuilder *D = unwrap(Dref);<br>
DICompositeType CT = D->createSubroutineType(<br>
unwrapDI<DIFile>(File), unwrapDI<DITypeArray>(<u></u>ParameterTypes));<br>
- return wrap(CT);<br>
+ return wrapDI(CT);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateStructType(<br>
@@ -139,7 +160,7 @@ LLVMValueRef LLVMDIBuilderCreateStructTy<br>
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,<br>
SizeInBits, AlignInBits, Flags, unwrapDI<DIType>(DerivedFrom),<br>
unwrapDI<DIArray>(<u></u>ElementTypes));<br>
- return wrap(CT);<br>
+ return wrapDI(CT);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateMemberType(<br>
@@ -150,7 +171,7 @@ LLVMValueRef LLVMDIBuilderCreateMemberTy<br>
DIDerivedType DT = D->createMemberType(<br>
unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,<br>
SizeInBits, AlignInBits, OffsetInBits, Flags, unwrapDI<DIType>(Ty));<br>
- return wrap(DT);<br>
+ return wrapDI(DT);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateArrayType(<u></u>LLVMDIBuilderRef Dref,<br>
@@ -162,7 +183,7 @@ LLVMValueRef LLVMDIBuilderCreateArrayTyp<br>
DICompositeType CT =<br>
D->createArrayType(SizeInBits, AlignInBits, unwrapDI<DIType>(ElementType),<br>
unwrapDI<DIArray>(Subscripts))<u></u>;<br>
- return wrap(CT);<br>
+ return wrapDI(CT);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateTypedef(<u></u>LLVMDIBuilderRef Dref, LLVMValueRef Ty,<br>
@@ -172,40 +193,36 @@ LLVMValueRef LLVMDIBuilderCreateTypedef(<br>
DIDerivedType DT =<br>
D->createTypedef(unwrapDI<<u></u>DIType>(Ty), Name, unwrapDI<DIFile>(File), Line,<br>
unwrapDI<DIDescriptor>(<u></u>Context));<br>
- return wrap(DT);<br>
+ return wrapDI(DT);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderGetOrCreateSubran<u></u>ge(LLVMDIBuilderRef Dref, int64_t Lo,<br>
int64_t Count) {<br>
DIBuilder *D = unwrap(Dref);<br>
DISubrange S = D->getOrCreateSubrange(Lo, Count);<br>
- return wrap(S);<br>
+ return wrapDI(S);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderGetOrCreateArray(<u></u>LLVMDIBuilderRef Dref,<br>
LLVMValueRef *Data, size_t Length) {<br>
DIBuilder *D = unwrap(Dref);<br>
- Value **DataValue = unwrap(Data);<br>
- ArrayRef<Value *> Elements(DataValue, Length);<br>
- DIArray A = D->getOrCreateArray(Elements);<br>
- return wrap(A);<br>
+ DIArray A = D->getOrCreateArray(<u></u>unwrapMetadataArray(Data, Length));<br>
+ return wrapDI(A);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderGetOrCreateTypeAr<u></u>ray(LLVMDIBuilderRef Dref,<br>
LLVMValueRef *Data,<br>
size_t Length) {<br>
DIBuilder *D = unwrap(Dref);<br>
- Value **DataValue = unwrap(Data);<br>
- ArrayRef<Value *> Elements(DataValue, Length);<br>
- DITypeArray A = D->getOrCreateTypeArray(<u></u>Elements);<br>
- return wrap(A);<br>
+ DITypeArray A = D->getOrCreateTypeArray(<u></u>unwrapMetadataArray(Data, Length));<br>
+ return wrapDI(A);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderCreateExpression(<u></u>LLVMDIBuilderRef Dref, int64_t *Addr,<br>
size_t Length) {<br>
DIBuilder *D = unwrap(Dref);<br>
DIExpression Expr = D->createExpression(ArrayRef<<u></u>int64_t>(Addr, Length));<br>
- return wrap(Expr);<br>
+ return wrapDI(Expr);<br>
}<br>
<br>
LLVMValueRef LLVMDIBuilderInsertDeclareAtEn<u></u>d(LLVMDIBuilderRef Dref,<br>
<br>
Modified: llvm/trunk/include/llvm-c/<u></u>Core.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm-c/Core.h?rev=223802&r1=<u></u>223801&r2=223802&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm-c/<u></u>Core.h (original)<br>
+++ llvm/trunk/include/llvm-c/<u></u>Core.h Tue Dec 9 12:38:53 2014<br>
@@ -1157,8 +1157,6 @@ LLVMTypeRef LLVMX86MMXType(void);<br>
macro(Argument) \<br>
macro(BasicBlock) \<br>
macro(InlineAsm) \<br>
- macro(MDNode) \<br>
- macro(MDString) \<br>
macro(User) \<br>
macro(Constant) \<br>
macro(BlockAddress) \<br>
@@ -1307,6 +1305,9 @@ LLVMBool LLVMIsUndef(LLVMValueRef Val);<br>
LLVMValueRef LLVMIsA##name(LLVMValueRef Val);<br>
LLVM_FOR_EACH_VALUE_SUBCLASS(<u></u>LLVM_DECLARE_VALUE_CAST)<br>
<br>
+LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val);<br>
+LLVMValueRef LLVMIsAMDString(LLVMValueRef Val);<br>
+<br>
/**<br>
* @}<br>
*/<br>
<br>
Modified: llvm/trunk/include/llvm/<u></u>CodeGen/LexicalScopes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LexicalScopes.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/CodeGen/LexicalScopes.h?<u></u>rev=223802&r1=223801&r2=<u></u>223802&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/<u></u>CodeGen/LexicalScopes.h (original)<br>
+++ llvm/trunk/include/llvm/<u></u>CodeGen/LexicalScopes.h Tue Dec 9 12:38:53 2014<br>
@@ -48,6 +48,8 @@ public:<br>
LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)<br>
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),<br>
LastInsn(nullptr), FirstInsn(nullptr), DFSIn(0), DFSOut(0) {<br>
+ assert((!D || D->isResolved()) && "Expected resolved node");<br>
+ assert((!I || I->isResolved()) && "Expected resolved node");<br>
if (Parent)<br>
Parent->addChild(this);<br>
}<br>
@@ -116,8 +118,8 @@ public:<br>
<br>
private:<br>
LexicalScope *Parent; // Parent to this scope.<br>
- AssertingVH<const MDNode> Desc; // Debug info descriptor.<br>
- AssertingVH<const MDNode> InlinedAtLocation; // Location at which this<br>
+ const MDNode *Desc; // Debug info descriptor.<br>
+ const MDNode *InlinedAtLocation; // Location at which this<br>
// scope is inlined.<br>
bool AbstractScope; // Abstract Scope<br>
SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope.<br>
<br>
Modified: llvm/trunk/include/llvm/<u></u>CodeGen/MachineInstr.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/CodeGen/MachineInstr.h?<u></u>rev=223802&r1=223801&r2=<u></u>223802&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/<u></u>CodeGen/MachineInstr.h (original)<br>
+++ llvm/trunk/include/llvm/<u></u>CodeGen/MachineInstr.h Tue Dec 9 12:38:53 2014<br>
@@ -1139,7 +1139,10 @@ public:<br>
/// setDebugLoc - Replace current source information with new such.<br>
/// Avoid using this, the constructor argument is preferable.<br>
///<br>
- void setDebugLoc(const DebugLoc dl) { debugLoc = dl; }<br>
+ void setDebugLoc(const DebugLoc dl) {<br>
+ debugLoc = dl;<br>
+ assert(debugLoc.<u></u>hasTrivialDestructor() && "Expected trivial destructor");<br>
+ }<br>
<br>
/// RemoveOperand - Erase an operand from an instruction, leaving it with one<br>
/// fewer operand than it started with.<br>
<br>
Modified: llvm/trunk/include/llvm/<u></u>CodeGen/MachineModuleInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/CodeGen/<u></u>MachineModuleInfo.h?rev=<u></u>223802&r1=223801&r2=223802&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/<u></u>CodeGen/MachineModuleInfo.h (original)<br>
+++ llvm/trunk/include/llvm/<u></u>CodeGen/MachineModuleInfo.h Tue Dec 9 12:38:53 2014<br>
@@ -165,10 +165,13 @@ public:<br>
static char ID; // Pass identification, replacement for typeid<br>
<br>
struct VariableDbgInfo {<br>
- TrackingVH<MDNode> Var;<br>
- TrackingVH<MDNode> Expr;<br>
+ TrackingMDNodeRef Var;<br>
+ TrackingMDNodeRef Expr;<br>
unsigned Slot;<br>
DebugLoc Loc;<br>
+<br>
+ VariableDbgInfo(MDNode *Var, MDNode *Expr, unsigned Slot, DebugLoc Loc)<br>
+ : Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {}<br>
};<br>
typedef SmallVector<VariableDbgInfo, 4> VariableDbgInfoMapTy;<br>
VariableDbgInfoMapTy VariableDbgInfos;<br>
@@ -393,8 +396,7 @@ public:<br>
/// information of a variable.<br>
void setVariableDbgInfo(MDNode *Var, MDNode *Expr, unsigned Slot,<br>
DebugLoc Loc) {<br>
- VariableDbgInfo Info = {Var, Expr, Slot, Loc};<br>
- VariableDbgInfos.push_back(<u></u>std::move(Info));<br>
+ VariableDbgInfos.emplace_back(<u></u>Var, Expr, Slot, Loc);<br>
}<br>
<br>
VariableDbgInfoMapTy &getVariableDbgInfo() { return VariableDbgInfos; }<br>
<br>
Modified: llvm/trunk/include/llvm/<u></u>CodeGen/SelectionDAGNodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/CodeGen/<u></u>SelectionDAGNodes.h?rev=<u></u>223802&r1=223801&r2=223802&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/<u></u>CodeGen/SelectionDAGNodes.h (original)<br>
+++ llvm/trunk/include/llvm/<u></u>CodeGen/SelectionDAGNodes.h Tue Dec 9 12:38:53 2014<br>
@@ -762,6 +762,7 @@ protected:<br>
ValueList(VTs.VTs), UseList(nullptr),<br>
NumOperands(Ops.size()), NumValues(VTs.NumVTs),<br>
debugLoc(dl), IROrder(Order) {<br>
+ assert(debugLoc.<u></u>hasTrivialDestructor() && "Expected trivial destructor");<br>
assert(NumOperands == Ops.size() &&<br>
"NumOperands wasn't wide enough for its operands!");<br>
assert(NumValues == VTs.NumVTs &&<br>
@@ -780,6 +781,7 @@ protected:<br>
SubclassData(0), NodeId(-1), OperandList(nullptr), ValueList(VTs.VTs),<br>
UseList(nullptr), NumOperands(0), NumValues(VTs.NumVTs), debugLoc(dl),<br>
IROrder(Order) {<br>
+ assert(debugLoc.<u></u>hasTrivialDestructor() && "Expected trivial destructor");<br>
assert(NumValues == VTs.NumVTs &&<br>
"NumValues wasn't wide enough for its operands!");<br>
}<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>DIBuilder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DIBuilder.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/DIBuilder.h?rev=<u></u>223802&r1=223801&r2=223802&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>DIBuilder.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>DIBuilder.h Tue Dec 9 12:38:53 2014<br>
@@ -18,6 +18,7 @@<br>
#include "llvm/ADT/ArrayRef.h"<br>
#include "llvm/ADT/StringRef.h"<br>
#include "llvm/IR/DebugInfo.h"<br>
+#include "llvm/IR/TrackingMDRef.h"<br>
#include "llvm/IR/ValueHandle.h"<br>
#include "llvm/Support/DataTypes.h"<br>
<br>
@@ -65,22 +66,34 @@ namespace llvm {<br>
Function *DeclareFn; // llvm.dbg.declare<br>
Function *ValueFn; // llvm.dbg.value<br>
<br>
- SmallVector<Value *, 4> AllEnumTypes;<br>
- /// Use TrackingVH to collect RetainTypes, since they can be updated<br>
- /// later on.<br>
- SmallVector<TrackingVH<MDNode><u></u>, 4> AllRetainTypes;<br>
- SmallVector<Value *, 4> AllSubprograms;<br>
- SmallVector<Value *, 4> AllGVs;<br>
- SmallVector<TrackingVH<MDNode><u></u>, 4> AllImportedModules;<br>
+ SmallVector<Metadata *, 4> AllEnumTypes;<br>
+ /// Track the RetainTypes, since they can be updated later on.<br>
+ SmallVector<TrackingMDNodeRef, 4> AllRetainTypes;<br>
+ SmallVector<Metadata *, 4> AllSubprograms;<br>
+ SmallVector<Metadata *, 4> AllGVs;<br>
+ SmallVector<TrackingMDNodeRef, 4> AllImportedModules;<br>
+<br>
+ /// \brief Track nodes that may be unresolved.<br>
+ SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes;<br>
+ bool AllowUnresolvedNodes;<br>
<br>
/// Each subprogram's preserved local variables.<br>
- DenseMap<MDNode *, std::vector<TrackingVH<MDNode><u></u>>> PreservedVariables;<br>
+ DenseMap<MDNode *, std::vector<TrackingMDNodeRef><u></u>> PreservedVariables;<br>
<br>
DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION;<br>
void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION;<br>
<br>
+ /// \brief Create a temporary.<br>
+ ///<br>
+ /// Create an \a MDNodeFwdDecl and track it in \a UnresolvedNodes.<br>
+ void trackIfUnresolved(MDNode *N);<br>
+<br>
public:<br>
- explicit DIBuilder(Module &M);<br>
+ /// \brief Construct a builder for a module.<br>
+ ///<br>
+ /// If \c AllowUnresolved, collect unresolved nodes attached to the module<br>
+ /// in order to resolve cycles during \a finalize().<br>
+ explicit DIBuilder(Module &M, bool AllowUnresolved = true);<br>
enum DebugEmissionKind { FullDebug=1, LineTablesOnly };<br>
<br>
/// finalize - Construct any deferred debug info descriptors.<br>
@@ -437,10 +450,10 @@ namespace llvm {<br>
DIBasicType createUnspecifiedParameter();<br>
<br>
/// getOrCreateArray - Get a DIArray, create one if required.<br>
- DIArray getOrCreateArray(ArrayRef<<u></u>Value *> Elements);<br>
+ DIArray getOrCreateArray(ArrayRef<<u></u>Metadata *> Elements);<br>
<br>
/// getOrCreateTypeArray - Get a DITypeArray, create one if required.<br>
- DITypeArray getOrCreateTypeArray(ArrayRef<<u></u>Value *> Elements);<br>
+ DITypeArray getOrCreateTypeArray(ArrayRef<<u></u>Metadata *> Elements);<br>
<br>
/// getOrCreateSubrange - Create a descriptor for a value range. This<br>
/// implicitly uniques the values returned.<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>DebugInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfo.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/DebugInfo.h?rev=<u></u>223802&r1=223801&r2=223802&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>DebugInfo.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>DebugInfo.h Tue Dec 9 12:38:53 2014<br>
@@ -168,8 +168,9 @@ public:<br>
<br>
bool Verify() const;<br>
<br>
- operator MDNode *() const { return const_cast<MDNode *>(DbgNode); }<br>
- MDNode *operator->() const { return const_cast<MDNode *>(DbgNode); }<br>
+ MDNode *get() const { return const_cast<MDNode *>(DbgNode); }<br>
+ operator MDNode *() const { return get(); }<br>
+ MDNode *operator->() const { return get(); }<br>
<br>
// An explicit operator bool so that we can do testing of DI values<br>
// easily.<br>
@@ -740,7 +741,7 @@ public:<br>
<br>
DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }<br>
DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }<br>
- Value *getValue() const;<br>
+ Metadata *getValue() const;<br>
StringRef getFilename() const { return getFieldAs<DIFile>(4).<u></u>getFilename(); }<br>
StringRef getDirectory() const {<br>
return getFieldAs<DIFile>(4).<u></u>getDirectory();<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>DebugLoc.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugLoc.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/DebugLoc.h?rev=223802&<u></u>r1=223801&r2=223802&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>DebugLoc.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>DebugLoc.h Tue Dec 9 12:38:53 2014<br>
@@ -16,50 +16,40 @@<br>
#define LLVM_IR_DEBUGLOC_H<br>
<br>
#include "llvm/Support/DataTypes.h"<br>
+#include "llvm/IR/TrackingMDRef.h"<br>
<br>
namespace llvm {<br>
- template <typename T> struct DenseMapInfo;<br>
- class MDNode;<br>
+<br>
class LLVMContext;<br>
class raw_ostream;<br>
+ class MDNode;<br>
<br>
/// DebugLoc - Debug location id. This is carried by Instruction, SDNode,<br>
/// and MachineInstr to compactly encode file/line/scope information for an<br>
/// operation.<br>
class DebugLoc {<br>
- friend struct DenseMapInfo<DebugLoc>;<br>
+ TrackingMDNodeRef Loc;<br>
<br>
- /// getEmptyKey() - A private constructor that returns an unknown that is<br>
- /// not equal to the tombstone key or DebugLoc().<br>
- static DebugLoc getEmptyKey() {<br>
- DebugLoc DL;<br>
- DL.LineCol = 1;<br>
- return DL;<br>
+ public:<br>
+ DebugLoc() {}<br>
+ DebugLoc(DebugLoc &&X) : Loc(std::move(X.Loc)) {}<br>
+ DebugLoc(const DebugLoc &X) : Loc(X.Loc) {}<br>
+ DebugLoc &operator=(DebugLoc &&X) {<br>
+ Loc = std::move(X.Loc);<br>
+ return *this;<br>
}<br>
-<br>
- /// getTombstoneKey() - A private constructor that returns an unknown that<br>
- /// is not equal to the empty key or DebugLoc().<br>
- static DebugLoc getTombstoneKey() {<br>
- DebugLoc DL;<br>
- DL.LineCol = 2;<br>
- return DL;<br>
+ DebugLoc &operator=(const DebugLoc &X) {<br>
+ Loc = X.Loc;<br>
+ return *this;<br>
}<br>
<br>
- /// LineCol - This 32-bit value encodes the line and column number for the<br>
- /// location, encoded as 24-bits for line and 8 bits for col. A value of 0<br>
- /// for either means unknown.<br>
- uint32_t LineCol;<br>
-<br>
- /// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information,<br>
- /// decoded by LLVMContext. 0 is unknown.<br>
- int ScopeIdx;<br>
- public:<br>
- DebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown.<br>
+ /// \brief Check whether this has a trivial destructor.<br>
+ bool hasTrivialDestructor() const { return Loc.hasTrivialDestructor(); }<br>
<br>
/// get - Get a new DebugLoc that corresponds to the specified line/col<br>
/// scope/inline location.<br>
- static DebugLoc get(unsigned Line, unsigned Col,<br>
- MDNode *Scope, MDNode *InlinedAt = nullptr);<br>
+ static DebugLoc get(unsigned Line, unsigned Col, MDNode *Scope,<br>
+ MDNode *InlinedAt = nullptr);<br>
<br>
/// getFromDILocation - Translate the DILocation quad into a DebugLoc.<br>
static DebugLoc getFromDILocation(MDNode *N);<br>
@@ -68,56 +58,54 @@ namespace llvm {<br>
static DebugLoc getFromDILexicalBlock(MDNode *N);<br>
<br>
/// isUnknown - Return true if this is an unknown location.<br>
- bool isUnknown() const { return ScopeIdx == 0; }<br>
+ bool isUnknown() const { return !Loc; }<br>
<br>
- unsigned getLine() const {<br>
- return (LineCol << 8) >> 8; // Mask out column.<br>
- }<br>
-<br>
- unsigned getCol() const {<br>
- return LineCol >> 24;<br>
- }<br>
+ unsigned getLine() const;<br>
+ unsigned getCol() const;<br>
<br>
/// getScope - This returns the scope pointer for this DebugLoc, or null if<br>
/// invalid.<br>
- MDNode *getScope(const LLVMContext &Ctx) const;<br>
+ MDNode *getScope() const;<br>
+ MDNode *getScope(const LLVMContext &) const { return getScope(); }<br>
<br>
/// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or<br>
/// null if invalid or not present.<br>
- MDNode *getInlinedAt(const LLVMContext &Ctx) const;<br>
+ MDNode *getInlinedAt() const;<br>
+ MDNode *getInlinedAt(const LLVMContext &) const { return getInlinedAt(); }<br>
<br>
/// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values.<br>
+ void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA) const;<br>
void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA,<br>
- const LLVMContext &Ctx) const;<br>
+ const LLVMContext &) const {<br>
+ return getScopeAndInlinedAt(Scope, IA);<br>
+ }<br>
<br>
/// getScopeNode - Get MDNode for DebugLoc's scope, or null if invalid.<br>
- MDNode *getScopeNode(const LLVMContext &Ctx) const;<br>
+ MDNode *getScopeNode() const;<br>
+ MDNode *getScopeNode(const LLVMContext &) const { return getScopeNode(); }<br>
<br>
// getFnDebugLoc - Walk up the scope chain of given debug loc and find line<br>
// number info for the function.<br>
- DebugLoc getFnDebugLoc(const LLVMContext &Ctx) const;<br>
+ DebugLoc getFnDebugLoc() const;<br>
+ DebugLoc getFnDebugLoc(const LLVMContext &) const {<br>
+ return getFnDebugLoc();<br>
+ }<br>
<br>
/// getAsMDNode - This method converts the compressed DebugLoc node into a<br>
/// DILocation compatible MDNode.<br>
- MDNode *getAsMDNode(const LLVMContext &Ctx) const;<br>
+ MDNode *getAsMDNode() const;<br>
+ MDNode *getAsMDNode(LLVMContext &) const { return getAsMDNode(); }<br>
<br>
- bool operator==(const DebugLoc &DL) const {<br>
- return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx;<br>
- }<br>
+ bool operator==(const DebugLoc &DL) const { return Loc == DL.Loc; }<br>
bool operator!=(const DebugLoc &DL) const { return !(*this == DL); }<br>
<br>
- void dump(const LLVMContext &Ctx) const;<br>
+ void dump() const;<br>
+ void dump(const LLVMContext &) const { dump(); }<br>
/// \brief prints source location /path/to/file.exe:line:col @[inlined at]<br>
- void print(const LLVMContext &Ctx, raw_ostream &OS) const;<br>
+ void print(raw_ostream &OS) const;<br>
+ void print(const LLVMContext &, raw_ostream &OS) const { print(OS); }<br>
};<br>
<br>
- template <><br>
- struct DenseMapInfo<DebugLoc> {<br>
- static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); }<br>
- static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); }<br>
- static unsigned getHashValue(const DebugLoc &Key);<br>
- static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; }<br>
- };<br>
} // end namespace llvm<br>
<br>
#endif /* LLVM_SUPPORT_DEBUGLOC_H */<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>IntrinsicInst.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicInst.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/IntrinsicInst.h?rev=<u></u>223802&r1=223801&r2=223802&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>IntrinsicInst.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>IntrinsicInst.h Tue Dec 9 12:38:53 2014<br>
@@ -28,6 +28,7 @@<br>
#include "llvm/IR/Function.h"<br>
#include "llvm/IR/Instructions.h"<br>
#include "llvm/IR/Intrinsics.h"<br>
+#include "llvm/IR/Metadata.h"<br>
<br>
namespace llvm {<br>
/// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic<br>
@@ -81,8 +82,14 @@ namespace llvm {<br>
class DbgDeclareInst : public DbgInfoIntrinsic {<br>
public:<br>
Value *getAddress() const;<br>
- MDNode *getVariable() const { return cast<MDNode>(getArgOperand(1))<u></u>; }<br>
- MDNode *getExpression() const { return cast<MDNode>(getArgOperand(2))<u></u>; }<br>
+ MDNode *getVariable() const {<br>
+ return cast<MDNode>(<br>
+ cast<MetadataAsValue>(<u></u>getArgOperand(1))-><u></u>getMetadata());<br>
+ }<br>
+ MDNode *getExpression() const {<br>
+ return cast<MDNode>(<br>
+ cast<MetadataAsValue>(<u></u>getArgOperand(2))-><u></u>getMetadata());<br>
+ }<br>
<br>
// Methods for support type inquiry through isa, cast, and dyn_cast:<br>
static inline bool classof(const IntrinsicInst *I) {<br>
@@ -103,8 +110,14 @@ namespace llvm {<br>
return cast<ConstantInt>(<br>
const_cast<Value*>(<u></u>getArgOperand(1)))-><u></u>getZExtValue();<br>
}<br>
- MDNode *getVariable() const { return cast<MDNode>(getArgOperand(2))<u></u>; }<br>
- MDNode *getExpression() const { return cast<MDNode>(getArgOperand(3))<u></u>; }<br>
+ MDNode *getVariable() const {<br>
+ return cast<MDNode>(<br>
+ cast<MetadataAsValue>(<u></u>getArgOperand(2))-><u></u>getMetadata());<br>
+ }<br>
+ MDNode *getExpression() const {<br>
+ return cast<MDNode>(<br>
+ cast<MetadataAsValue>(<u></u>getArgOperand(3))-><u></u>getMetadata());<br>
+ }<br>
<br>
// Methods for support type inquiry through isa, cast, and dyn_cast:<br>
static inline bool classof(const IntrinsicInst *I) {<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>MDBuilder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/MDBuilder.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/MDBuilder.h?rev=<u></u>223802&r1=223801&r2=223802&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>MDBuilder.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>MDBuilder.h Tue Dec 9 12:38:53 2014<br>
@@ -24,6 +24,8 @@ namespace llvm {<br>
class APInt;<br>
template <typename T> class ArrayRef;<br>
class LLVMContext;<br>
+class Constant;<br>
+class ConstantAsMetadata;<br>
class MDNode;<br>
class MDString;<br>
<br>
@@ -36,6 +38,9 @@ public:<br>
/// \brief Return the given string as metadata.<br>
MDString *createString(StringRef Str);<br>
<br>
+ /// \brief Return the given constant as metadata.<br>
+ ConstantAsMetadata *createConstant(Constant *C);<br>
+<br>
//===-------------------------<u></u>------------------------------<u></u>-----------===//<br>
// FPMath metadata.<br>
//===-------------------------<u></u>------------------------------<u></u>-----------===//<br>
<br>
Added: llvm/trunk/include/llvm/IR/<u></u>Metadata.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.def?rev=223802&view=auto" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/Metadata.def?rev=<u></u>223802&view=auto</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>Metadata.def (added)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>Metadata.def Tue Dec 9 12:38:53 2014<br>
@@ -0,0 +1,44 @@<br>
+//===- llvm/Metadata.def - Metadata definitions -----------------*- C++ -*-===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<br>
+//<br>
+// Macros for running through all types of metadata.<br>
+//<br>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<br>
+<br>
+#if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \<br>
+ defined HANDLE_METADATA_BRANCH)<br>
+#error "Missing macro definition of HANDLE_METADATA*"<br>
+#endif<br>
+<br>
+// Handler for all types of metadata.<br>
+#ifndef HANDLE_METADATA<br>
+#define HANDLE_METADATA(CLASS)<br>
+#endif<br>
+<br>
+// Handler for leaf nodes in the class hierarchy.<br>
+#ifndef HANDLE_METADATA_LEAF<br>
+#define HANDLE_METADATA_LEAF(CLASS) HANDLE_METADATA(CLASS)<br>
+#endif<br>
+<br>
+// Handler for non-leaf nodes in the class hierarchy.<br>
+#ifndef HANDLE_METADATA_BRANCH<br>
+#define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS)<br>
+#endif<br>
+<br>
+HANDLE_METADATA_LEAF(<u></u>MDString)<br>
+HANDLE_METADATA_BRANCH(<u></u>ValueAsMetadata)<br>
+HANDLE_METADATA_LEAF(<u></u>ConstantAsMetadata)<br>
+HANDLE_METADATA_LEAF(<u></u>LocalAsMetadata)<br>
+HANDLE_METADATA_BRANCH(<u></u>MDNode)<br>
+HANDLE_METADATA_LEAF(<u></u>MDNodeFwdDecl)<br>
+HANDLE_METADATA_LEAF(<u></u>GenericMDNode)<br>
+<br>
+#undef HANDLE_METADATA<br>
+#undef HANDLE_METADATA_LEAF<br>
+#undef HANDLE_METADATA_BRANCH<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>Metadata.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/Metadata.h?rev=223802&<u></u>r1=223801&r2=223802&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>Metadata.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>Metadata.h Tue Dec 9 12:38:53 2014<br>
@@ -18,11 +18,13 @@<br>
<br>
#include "llvm/ADT/ArrayRef.h"<br>
#include "llvm/ADT/DenseMap.h"<br>
-#include "llvm/ADT/FoldingSet.h"<br>
#include "llvm/ADT/ilist_node.h"<br>
#include "llvm/ADT/iterator_range.h"<br>
+#include "llvm/IR/Constant.h"<br>
+#include "llvm/IR/MetadataTracking.h"<br>
#include "llvm/IR/Value.h"<br>
#include "llvm/Support/ErrorHandling.h"<br>
+#include <type_traits><br>
<br>
namespace llvm {<br>
class LLVMContext;<br>
@@ -38,20 +40,388 @@ enum LLVMConstants : uint32_t {<br>
/// \brief Root of the metadata hierarchy.<br>
///<br>
/// This is a root class for typeless data in the IR.<br>
-///<br>
-/// TODO: Detach from the Value hierarchy.<br>
-class Metadata : public Value {<br>
+class Metadata {<br>
+ friend class ReplaceableMetadataImpl;<br>
+<br>
+ /// \brief RTTI.<br>
+ const unsigned char SubclassID;<br>
+<br>
protected:<br>
- Metadata(LLVMContext &Context, unsigned ID);<br>
+ /// \brief Storage flag for non-uniqued, otherwise unowned, metadata.<br>
+ bool IsDistinctInContext : 1;<br>
+ // TODO: expose remaining bits to subclasses.<br>
+<br>
+ unsigned short SubclassData16;<br>
+ unsigned SubclassData32;<br>
+<br>
+public:<br>
+ enum MetadataKind {<br>
+ GenericMDNodeKind,<br>
+ MDNodeFwdDeclKind,<br>
+ ConstantAsMetadataKind,<br>
+ LocalAsMetadataKind,<br>
+ MDStringKind<br>
+ };<br>
+<br>
+protected:<br>
+ Metadata(unsigned ID)<br>
+ : SubclassID(ID), IsDistinctInContext(false), SubclassData16(0),<br>
+ SubclassData32(0) {}<br>
+ ~Metadata() {}<br>
+<br>
+ /// \brief Store this in a big non-uniqued untyped bucket.<br>
+ bool isStoredDistinctInContext() const { return IsDistinctInContext; }<br>
+<br>
+ /// \brief Default handling of a changed operand, which asserts.<br>
+ ///<br>
+ /// If subclasses pass themselves in as owners to a tracking node reference,<br>
+ /// they must provide an implementation of this method.<br>
+ void handleChangedOperand(void *, Metadata *) {<br>
+ llvm_unreachable("<u></u>Unimplemented in Metadata subclass");<br>
+ }<br>
<br>
public:<br>
+ unsigned getMetadataID() const { return SubclassID; }<br>
+<br>
+ /// \brief User-friendly dump.<br>
+ void dump() const;<br>
+ void print(raw_ostream &OS) const;<br>
+ void printAsOperand(raw_ostream &OS, bool PrintType = true,<br>
+ const Module *M = nullptr) const;<br>
+};<br>
+<br>
+#define HANDLE_METADATA(CLASS) class CLASS;<br>
+#include "llvm/IR/Metadata.def"<br>
+<br>
+inline raw_ostream &operator<<(raw_ostream &OS, const Metadata &MD) {<br>
+ MD.print(OS);<br>
+ return OS;<br>
+}<br>
+<br>
+/// \brief Metadata wrapper in the Value hierarchy.<br>
+///<br>
+/// A member of the \a Value hierarchy to represent a reference to metadata.<br>
+/// This allows, e.g., instrinsics to have metadata as operands.<br>
+///<br>
+/// Notably, this is the only thing in either hierarchy that is allowed to<br>
+/// reference \a LocalAsMetadata.<br>
+class MetadataAsValue : public Value {<br>
+ friend class ReplaceableMetadataImpl;<br>
+ friend class LLVMContextImpl;<br>
+<br>
+ Metadata *MD;<br>
+<br>
+ MetadataAsValue(Type *Ty, Metadata *MD);<br>
+ ~MetadataAsValue();<br>
+<br>
+public:<br>
+ static MetadataAsValue *get(LLVMContext &Context, Metadata *MD);<br>
+ static MetadataAsValue *getIfExists(LLVMContext &Context, Metadata *MD);<br>
+ Metadata *getMetadata() const { return MD; }<br>
+<br>
static bool classof(const Value *V) {<br>
- return V->getValueID() == GenericMDNodeVal ||<br>
- V->getValueID() == MDNodeFwdDeclVal ||<br>
- V->getValueID() == MDStringVal;<br>
+ return V->getValueID() == MetadataAsValueVal;<br>
+ }<br>
+<br>
+private:<br>
+ void handleChangedMetadata(Metadata *MD);<br>
+ void track();<br>
+ void untrack();<br>
+};<br>
+<br>
+/// \brief Shared implementation of use-lists for replaceable metadata.<br>
+///<br>
+/// Most metadata cannot be RAUW'ed. This is a shared implementation of<br>
+/// use-lists and associated API for the two that support it (\a ValueAsMetadata<br>
+/// and \a TempMDNode).<br>
+class ReplaceableMetadataImpl {<br>
+ friend class MetadataTracking;<br>
+<br>
+public:<br>
+ typedef MetadataTracking::OwnerTy OwnerTy;<br>
+<br>
+private:<br>
+ SmallDenseMap<void *, OwnerTy, 4> UseMap;<br>
+<br>
+public:<br>
+ ~ReplaceableMetadataImpl() {<br>
+ assert(UseMap.empty() && "Cannot destroy in-use replaceable metadata");<br>
+ }<br>
+<br>
+ /// \brief Replace all uses of this with MD.<br>
+ ///<br>
+ /// Replace all uses of this with \c MD, which is allowed to be null.<br>
+ void replaceAllUsesWith(Metadata *MD);<br>
+<br>
+ /// \brief Resolve all uses of this.<br>
+ ///<br>
+ /// Resolve all uses of this, turning off RAUW permanently. If \c<br>
+ /// ResolveUsers, call \a GenericMDNode::resolve() on any users whose last<br>
+ /// operand is resolved.<br>
+ void resolveAllUses(bool ResolveUsers = true);<br>
+<br>
+private:<br>
+ void addRef(void *Ref, OwnerTy Owner);<br>
+ void dropRef(void *Ref);<br>
+ void moveRef(void *Ref, void *New, const Metadata &MD);<br>
+<br>
+ static ReplaceableMetadataImpl *get(Metadata &MD);<br>
+};<br>
+<br>
+/// \brief Value wrapper in the Metadata hierarchy.<br>
+///<br>
+/// This is a custom value handle that allows other metadata to refer to<br>
+/// classes in the Value hierarchy.<br>
+///<br>
+/// Because of full uniquing support, each value is only wrapped by a single \a<br>
+/// ValueAsMetadata object, so the lookup maps are far more efficient than<br>
+/// those using ValueHandleBase.<br>
+class ValueAsMetadata : public Metadata, ReplaceableMetadataImpl {<br>
+ friend class ReplaceableMetadataImpl;<br>
+ friend class LLVMContextImpl;<br>
+<br>
+ Value *V;<br>
+<br>
+protected:<br>
+ ValueAsMetadata(LLVMContext &Context, unsigned ID, Value *V)<br>
+ : Metadata(ID), V(V) {<br>
+ assert(V && "Expected valid value");<br>
+ }<br>
+ ~ValueAsMetadata() {}<br>
+<br>
+public:<br>
+ static ValueAsMetadata *get(Value *V);<br>
+ static ConstantAsMetadata *getConstant(Value *C) {<br>
+ return cast<ConstantAsMetadata>(get(<u></u>C));<br>
+ }<br>
+ static LocalAsMetadata *getLocal(Value *Local) {<br>
+ return cast<LocalAsMetadata>(get(<u></u>Local));<br>
+ }<br>
+<br>
+ static ValueAsMetadata *getIfExists(Value *V);<br>
+ static ConstantAsMetadata *getConstantIfExists(Value *C) {<br>
+ return cast_or_null<<u></u>ConstantAsMetadata>(<u></u>getIfExists(C));<br>
+ }<br>
+ static LocalAsMetadata *getLocalIfExists(Value *Local) {<br>
+ return cast_or_null<LocalAsMetadata>(<u></u>getIfExists(Local));<br>
+ }<br>
+<br>
+ Value *getValue() const { return V; }<br>
+ Type *getType() const { return V->getType(); }<br>
+ LLVMContext &getContext() const { return V->getContext(); }<br>
+<br>
+ static void handleDeletion(Value *V);<br>
+ static void handleRAUW(Value *From, Value *To);<br>
+<br>
+protected:<br>
+ /// \brief Handle collisions after \a Value::replaceAllUsesWith().<br>
+ ///<br>
+ /// RAUW isn't supported directly for \a ValueAsMetadata, but if the wrapped<br>
+ /// \a Value gets RAUW'ed and the target already exists, this is used to<br>
+ /// merge the two metadata nodes.<br>
+ void replaceAllUsesWith(Metadata *MD) {<br>
+ ReplaceableMetadataImpl::<u></u>replaceAllUsesWith(MD);<br>
+ }<br>
+<br>
+public:<br>
+ static bool classof(const Metadata *MD) {<br>
+ return MD->getMetadataID() == LocalAsMetadataKind ||<br>
+ MD->getMetadataID() == ConstantAsMetadataKind;<br>
}<br>
};<br>
<br>
+class ConstantAsMetadata : public ValueAsMetadata {<br>
+ friend class ValueAsMetadata;<br>
+<br>
+ ConstantAsMetadata(LLVMContext &Context, Constant *C)<br>
+ : ValueAsMetadata(Context, ConstantAsMetadataKind, C) {}<br>
+<br>
+public:<br>
+ static ConstantAsMetadata *get(Constant *C) {<br>
+ return ValueAsMetadata::getConstant(<u></u>C);<br>
+ }<br>
+ static ConstantAsMetadata *getIfExists(Constant *C) {<br>
+ return ValueAsMetadata::<u></u>getConstantIfExists(C);<br>
+ }<br>
+<br>
+ Constant *getValue() const {<br>
+ return cast<Constant>(<u></u>ValueAsMetadata::getValue());<br>
+ }<br>
+<br>
+ static bool classof(const Metadata *MD) {<br>
+ return MD->getMetadataID() == ConstantAsMetadataKind;<br>
+ }<br>
+};<br>
+<br>
+class LocalAsMetadata : public ValueAsMetadata {<br>
+ friend class ValueAsMetadata;<br>
+<br>
+ LocalAsMetadata(LLVMContext &Context, Value *Local)<br>
+ : ValueAsMetadata(Context, LocalAsMetadataKind, Local) {<br>
+ assert(!isa<Constant>(Local) && "Expected local value");<br>
+ }<br>
+<br>
+public:<br>
+ static LocalAsMetadata *get(Value *Local) {<br>
+ return ValueAsMetadata::getLocal(<u></u>Local);<br>
+ }<br>
+ static LocalAsMetadata *getIfExists(Value *Local) {<br>
+ return ValueAsMetadata::<u></u>getLocalIfExists(Local);<br>
+ }<br>
+<br>
+ static bool classof(const Metadata *MD) {<br>
+ return MD->getMetadataID() == LocalAsMetadataKind;<br>
+ }<br>
+};<br>
+<br>
+/// \brief Transitional API for extracting constants from Metadata.<br>
+///<br>
+/// This namespace contains transitional functions for metadata that points to<br>
+/// \a Constants.<br>
+///<br>
+/// In prehistory -- when metadata was a subclass of \a Value -- \a MDNode<br>
+/// operands could refer to any \a Value. There's was a lot of code like this:<br>
+///<br>
+/// \code<br>
+/// MDNode *N = ...;<br>
+/// auto *CI = dyn_cast<ConstantInt>(N-><u></u>getOperand(2));<br>
+/// \endcode<br>
+///<br>
+/// Now that \a Value and \a Metadata are in separate hierarchies, maintaining<br>
+/// the semantics for \a isa(), \a cast(), \a dyn_cast() (etc.) requires three<br>
+/// steps: cast in the \a Metadata hierarchy, extraction of the \a Value, and<br>
+/// cast in the \a Value hierarchy. Besides creating boiler-plate, this<br>
+/// requires subtle control flow changes.<br>
+///<br>
+/// The end-goal is to create a new type of metadata, called (e.g.) \a MDInt,<br>
+/// so that metadata can refer to numbers without traversing a bridge to the \a<br>
+/// Value hierarchy. In this final state, the code above would look like this:<br>
+///<br>
+/// \code<br>
+/// MDNode *N = ...;<br>
+/// auto *MI = dyn_cast<MDInt>(N->getOperand(<u></u>2));<br>
+/// \endcode<br>
+///<br>
+/// The API in this namespace supports the transition. \a MDInt doesn't exist<br>
+/// yet, and even once it does, changing each metadata schema to use it is its<br>
+/// own mini-project. In the meantime this API prevents us from introducing<br>
+/// complex and bug-prone control flow that will disappear in the end. In<br>
+/// particular, the above code looks like this:<br>
+///<br>
+/// \code<br>
+/// MDNode *N = ...;<br>
+/// auto *CI = mdconst::dyn_extract<<u></u>ConstantInt>(N->getOperand(2))<u></u>;<br>
+/// \endcode<br>
+///<br>
+/// The full set of provided functions includes:<br>
+///<br>
+/// mdconst::hasa <=> isa<br>
+/// mdconst::extract <=> cast<br>
+/// mdconst::extract_or_null <=> cast_or_null<br>
+/// mdconst::dyn_extract <=> dyn_cast<br>
+/// mdconst::dyn_extract_or_null <=> dyn_cast_or_null<br>
+///<br>
+/// The target of the cast must be a subclass of \a Constant.<br>
+namespace mdconst {<br>
+<br>
+namespace detail {<br>
+template <class T> T &make();<br>
+template <class T, class Result> struct HasDereference {<br>
+ typedef char Yes[1];<br>
+ typedef char No[2];<br>
+ template <size_t N> struct SFINAE {};<br>
+<br>
+ template <class U, class V><br>
+ static Yes &hasDereference(SFINAE<sizeof(<u></u>static_cast<V>(*make<U>()))> * = 0);<br>
+ template <class U, class V> static No &hasDereference(...);<br>
+<br>
+ static const bool value =<br>
+ sizeof(hasDereference<T, Result>(nullptr)) == sizeof(Yes);<br>
+};<br>
+template <class V, class M> struct IsValidPointer {<br>
+ static const bool value = std::is_base_of<Constant, V>::value &&<br>
+ HasDereference<M, const Metadata &>::value;<br>
+};<br>
+template <class V, class M> struct IsValidReference {<br>
+ static const bool value = std::is_base_of<Constant, V>::value &&<br>
+ std::is_convertible<M, const Metadata &>::value;<br>
+};<br>
+} // end namespace detail<br>
+<br>
+/// \brief Check whether Metadata has a Value.<br>
+///<br>
+/// As an analogue to \a isa(), check whether \c MD has an \a Value inside of<br>
+/// type \c X.<br>
+template <class X, class Y><br>
+inline typename std::enable_if<detail::<u></u>IsValidPointer<X, Y>::value, bool>::type<br>
+hasa(Y &&MD) {<br>
+ assert(MD && "Null pointer sent into hasa");<br>
+ if (auto *V = dyn_cast<ConstantAsMetadata>(<u></u>MD))<br>
+ return isa<X>(V->getValue());<br>
+ return false;<br>
+}<br>
+template <class X, class Y><br>
+inline<br>
+ typename std::enable_if<detail::<u></u>IsValidReference<X, Y &>::value, bool>::type<br>
+ hasa(Y &MD) {<br>
+ return hasa(&MD);<br>
+}<br>
+<br>
+/// \brief Extract a Value from Metadata.<br>
+///<br>
+/// As an analogue to \a cast(), extract the \a Value subclass \c X from \c MD.<br>
+template <class X, class Y><br>
+inline typename std::enable_if<detail::<u></u>IsValidPointer<X, Y>::value, X *>::type<br>
+extract(Y &&MD) {<br>
+ return cast<X>(cast<<u></u>ConstantAsMetadata>(MD)-><u></u>getValue());<br>
+}<br>
+template <class X, class Y><br>
+inline<br>
+ typename std::enable_if<detail::<u></u>IsValidReference<X, Y &>::value, X *>::type<br>
+ extract(Y &MD) {<br>
+ return extract(&MD);<br>
+}<br>
+<br>
+/// \brief Extract a Value from Metadata, allowing null.<br>
+///<br>
+/// As an analogue to \a cast_or_null(), extract the \a Value subclass \c X<br>
+/// from \c MD, allowing \c MD to be null.<br>
+template <class X, class Y><br>
+inline typename std::enable_if<detail::<u></u>IsValidPointer<X, Y>::value, X *>::type<br>
+extract_or_null(Y &&MD) {<br>
+ if (auto *V = cast_or_null<<u></u>ConstantAsMetadata>(MD))<br>
+ return cast<X>(V->getValue());<br>
+ return nullptr;<br>
+}<br>
+<br>
+/// \brief Extract a Value from Metadata, if any.<br>
+///<br>
+/// As an analogue to \a dyn_cast_or_null(), extract the \a Value subclass \c X<br>
+/// from \c MD, return null if \c MD doesn't contain a \a Value or if the \a<br>
+/// Value it does contain is of the wrong subclass.<br>
+template <class X, class Y><br>
+inline typename std::enable_if<detail::<u></u>IsValidPointer<X, Y>::value, X *>::type<br>
+dyn_extract(Y &&MD) {<br>
+ if (auto *V = dyn_cast<ConstantAsMetadata>(<u></u>MD))<br>
+ return dyn_cast<X>(V->getValue());<br>
+ return nullptr;<br>
+}<br>
+<br>
+/// \brief Extract a Value from Metadata, if any, allowing null.<br>
+///<br>
+/// As an analogue to \a dyn_cast_or_null(), extract the \a Value subclass \c X<br>
+/// from \c MD, return null if \c MD doesn't contain a \a Value or if the \a<br>
+/// Value it does contain is of the wrong subclass, allowing \c MD to be null.<br>
+template <class X, class Y><br>
+inline typename std::enable_if<detail::<u></u>IsValidPointer<X, Y>::value, X *>::type<br>
+dyn_extract_or_null(Y &&MD) {<br>
+ if (auto *V = dyn_cast_or_null<<u></u>ConstantAsMetadata>(MD))<br>
+ return dyn_cast<X>(V->getValue());<br>
+ return nullptr;<br>
+}<br>
+<br>
+} // end namespace mdconst<br>
+<br>
//===-------------------------<u></u>------------------------------<u></u>---------------===//<br>
/// \brief A single uniqued string.<br>
///<br>
@@ -60,15 +430,13 @@ public:<br>
class MDString : public Metadata {<br>
friend class StringMapEntry<MDString>;<br>
<br>
- virtual void anchor();<br>
MDString(const MDString &) LLVM_DELETED_FUNCTION;<br>
+ MDString &operator=(MDString &&) LLVM_DELETED_FUNCTION;<br>
+ MDString &operator=(const MDString &) LLVM_DELETED_FUNCTION;<br>
<br>
StringMapEntry<MDString> *Entry;<br>
- explicit MDString(LLVMContext &Context)<br>
- : Metadata(Context, Value::MDStringVal), Entry(nullptr) {}<br>
-<br>
- /// \brief Shadow Value::getName() to prevent its use.<br>
- StringRef getName() const LLVM_DELETED_FUNCTION;<br>
+ MDString() : Metadata(MDStringKind), Entry(nullptr) {}<br>
+ MDString(MDString &&) : Metadata(MDStringKind) {}<br>
<br>
public:<br>
static MDString *get(LLVMContext &Context, StringRef Str);<br>
@@ -89,8 +457,8 @@ public:<br>
iterator end() const { return getString().end(); }<br>
<br>
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast.<br>
- static bool classof(const Value *V) {<br>
- return V->getValueID() == MDStringVal;<br>
+ static bool classof(const Metadata *MD) {<br>
+ return MD->getMetadataID() == MDStringKind;<br>
}<br>
};<br>
<br>
@@ -138,18 +506,80 @@ struct DenseMapInfo<AAMDNodes> {<br>
}<br>
};<br>
<br>
-class MDNodeOperand;<br>
+/// \brief Tracking metadata reference owned by Metadata.<br>
+///<br>
+/// Similar to \a TrackingMDRef, but it's expected to be owned by an instance<br>
+/// of \a Metadata, which has the option of registering itself for callbacks to<br>
+/// re-unique itself.<br>
+///<br>
+/// In particular, this is used by \a MDNode.<br>
+class MDOperand {<br>
+ MDOperand(MDOperand &&) LLVM_DELETED_FUNCTION;<br>
+ MDOperand(const MDOperand &) LLVM_DELETED_FUNCTION;<br>
+ MDOperand &operator=(MDOperand &&) LLVM_DELETED_FUNCTION;<br>
+ MDOperand &operator=(const MDOperand &) LLVM_DELETED_FUNCTION;<br>
+<br>
+ Metadata *MD;<br>
+<br>
+public:<br>
+ MDOperand() : MD(nullptr) {}<br>
+ ~MDOperand() { untrack(); }<br>
+<br>
+ LLVM_EXPLICIT operator bool() const { return get(); }<br>
+ Metadata *get() const { return MD; }<br>
+ operator Metadata *() const { return get(); }<br>
+ Metadata *operator->() const { return get(); }<br>
+ Metadata &operator*() const { return *get(); }<br>
+<br>
+ void reset() {<br>
+ untrack();<br>
+ MD = nullptr;<br>
+ }<br>
+ void reset(Metadata *MD, Metadata *Owner) {<br>
+ untrack();<br>
+ this->MD = MD;<br>
+ track(Owner);<br>
+ }<br>
+<br>
+private:<br>
+ void track(Metadata *Owner) {<br>
+ if (MD) {<br>
+ if (Owner)<br>
+ MetadataTracking::track(this, *MD, *Owner);<br>
+ else<br>
+ MetadataTracking::track(MD);<br>
+ }<br>
+ }<br>
+ void untrack() {<br>
+ assert(static_cast<void *>(this) == &MD && "Expected same address");<br>
+ if (MD)<br>
+ MetadataTracking::untrack(MD);<br>
+ }<br>
+};<br>
+<br>
+template <> struct simplify_type<MDOperand> {<br>
+ typedef Metadata *SimpleType;<br>
+ static SimpleType getSimplifiedValue(MDOperand &MD) { return MD.get(); }<br>
+};<br>
+<br>
+template <> struct simplify_type<const MDOperand> {<br>
+ typedef Metadata *SimpleType;<br>
+ static SimpleType getSimplifiedValue(const MDOperand &MD) { return MD.get(); }<br>
+};<br>
<br>
//===-------------------------<u></u>------------------------------<u></u>---------------===//<br>
/// \brief Tuple of metadata.<br>
class MDNode : public Metadata {<br>
MDNode(const MDNode &) LLVM_DELETED_FUNCTION;<br>
void operator=(const MDNode &) LLVM_DELETED_FUNCTION;<br>
- friend class MDNodeOperand;<br>
- friend class LLVMContextImpl;<br>
void *operator new(size_t) LLVM_DELETED_FUNCTION;<br>
<br>
+ LLVMContext &Context;<br>
+ unsigned NumOperands;<br>
+<br>
protected:<br>
+ unsigned MDNodeSubclassData;<br>
+<br>
void *operator new(size_t Size, unsigned NumOps);<br>
<br>
/// \brief Required by std, but never called.<br>
@@ -165,83 +595,83 @@ protected:<br>
llvm_unreachable("Constructor throws?");<br>
}<br>
<br>
- /// \brief Subclass data enums.<br>
- enum {<br>
- /// FunctionLocalBit - This bit is set if this MDNode is function local.<br>
- /// This is true when it (potentially transitively) contains a reference to<br>
- /// something in a function, like an argument, basicblock, or instruction.<br>
- FunctionLocalBit = 1 << 0,<br>
-<br>
- /// NotUniquedBit - This is set on MDNodes that are not uniqued because they<br>
- /// have a null operand.<br>
- NotUniquedBit = 1 << 1<br>
- };<br>
+ MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs);<br>
+ ~MDNode() { dropAllReferences(); }<br>
<br>
- /// \brief FunctionLocal enums.<br>
- enum FunctionLocalness {<br>
- FL_Unknown = -1,<br>
- FL_No = 0,<br>
- FL_Yes = 1<br>
- };<br>
+ void dropAllReferences();<br>
+ void storeDistinctInContext();<br>
<br>
- /// \brief Replace each instance of the given operand with a new value.<br>
- void replaceOperand(MDNodeOperand *Op, Value *NewVal);<br>
+ static MDNode *getMDNode(LLVMContext &C, ArrayRef<Metadata *> MDs,<br>
+ bool Insert = true);<br>
<br>
- MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,<br>
- bool isFunctionLocal);<br>
- ~MDNode() {}<br>
+ MDOperand *mutable_begin() { return mutable_end() - NumOperands; }<br>
+ MDOperand *mutable_end() { return reinterpret_cast<MDOperand *>(this); }<br>
<br>
- static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,<br>
- FunctionLocalness FL, bool Insert = true);<br>
public:<br>
- static MDNode *get(LLVMContext &Context, ArrayRef<Value*> Vals);<br>
- /// \brief Construct MDNode with an explicit function-localness.<br>
- ///<br>
- /// Don't analyze Vals; trust isFunctionLocal.<br>
+ static MDNode *get(LLVMContext &Context, ArrayRef<Metadata *> MDs) {<br>
+ return getMDNode(Context, MDs, true);<br>
+ }<br>
static MDNode *getWhenValsUnresolved(<u></u>LLVMContext &Context,<br>
- ArrayRef<Value*> Vals,<br>
- bool isFunctionLocal);<br>
+ ArrayRef<Metadata *> MDs) {<br>
+ // TODO: Remove this.<br>
+ return get(Context, MDs);<br>
+ }<br>
<br>
- static MDNode *getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals);<br>
+ static MDNode *getIfExists(LLVMContext &Context, ArrayRef<Metadata *> MDs) {<br>
+ return getMDNode(Context, MDs, false);<br>
+ }<br>
<br>
/// \brief Return a temporary MDNode<br>
///<br>
/// For use in constructing cyclic MDNode structures. A temporary MDNode is<br>
/// not uniqued, may be RAUW'd, and must be manually deleted with<br>
/// deleteTemporary.<br>
- static MDNode *getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals);<br>
+ static MDNodeFwdDecl *getTemporary(LLVMContext &Context,<br>
+ ArrayRef<Metadata *> MDs);<br>
<br>
/// \brief Deallocate a node created by getTemporary.<br>
///<br>
/// The node must not have any users.<br>
static void deleteTemporary(MDNode *N);<br>
<br>
+ LLVMContext &getContext() const { return Context; }<br>
+<br>
/// \brief Replace a specific operand.<br>
- void replaceOperandWith(unsigned i, Value *NewVal);<br>
+ void replaceOperandWith(unsigned I, Metadata *New);<br>
<br>
- /// \brief Return specified operand.<br>
- Value *getOperand(unsigned i) const LLVM_READONLY;<br>
+ /// \brief Check if node is fully resolved.<br>
+ bool isResolved() const;<br>
<br>
- /// \brief Return number of MDNode operands.<br>
- unsigned getNumOperands() const { return NumOperands; }<br>
+protected:<br>
+ /// \brief Set an operand.<br>
+ ///<br>
+ /// Sets the operand directly, without worrying about uniquing.<br>
+ void setOperand(unsigned I, Metadata *New);<br>
+<br>
+public:<br>
+ typedef const MDOperand *op_iterator;<br>
+ typedef iterator_range<op_iterator> op_range;<br>
<br>
- /// \brief Return whether MDNode is local to a function.<br>
- bool isFunctionLocal() const {<br>
- return (getSubclassDataFromValue() & FunctionLocalBit) != 0;<br>
+ op_iterator op_begin() const {<br>
+ return const_cast<MDNode *>(this)->mutable_begin();<br>
+ }<br>
+ op_iterator op_end() const {<br>
+ return const_cast<MDNode *>(this)->mutable_end();<br>
}<br>
+ op_range operands() const { return op_range(op_begin(), op_end()); }<br>
<br>
- /// \brief Return the first function-local operand's function.<br>
- ///<br>
- /// If this metadata is function-local and recursively has a function-local<br>
- /// operand, return the first such operand's parent function. Otherwise,<br>
- /// return null. getFunction() should not be used for performance- critical<br>
- /// code because it recursively visits all the MDNode's operands.<br>
- const Function *getFunction() const;<br>
+ const MDOperand &getOperand(unsigned I) const {<br>
+ assert(I < NumOperands && "Out of range");<br>
+ return op_begin()[I];<br>
+ }<br>
+<br>
+ /// \brief Return number of MDNode operands.<br>
+ unsigned getNumOperands() const { return NumOperands; }<br>
<br>
/// \brief Methods for support type inquiry through isa, cast, and dyn_cast:<br>
- static bool classof(const Value *V) {<br>
- return V->getValueID() == GenericMDNodeVal ||<br>
- V->getValueID() == MDNodeFwdDeclVal;<br>
+ static bool classof(const Metadata *MD) {<br>
+ return MD->getMetadataID() == GenericMDNodeKind ||<br>
+ MD->getMetadataID() == MDNodeFwdDeclKind;<br>
}<br>
<br>
/// \brief Check whether MDNode is a vtable access.<br>
@@ -254,18 +684,6 @@ public:<br>
static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B);<br>
static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);<br>
static MDNode *getMostGenericRange(MDNode *A, MDNode *B);<br>
-<br>
-protected:<br>
- bool isNotUniqued() const {<br>
- return (getSubclassDataFromValue() & NotUniquedBit) != 0;<br>
- }<br>
- void setIsNotUniqued();<br>
-<br>
- // Shadow Value::setValueSubclassData with a private forwarding method so that<br>
- // any future subclasses cannot accidentally use it.<br>
- void setValueSubclassData(unsigned short D) {<br>
- Value::setValueSubclassData(D)<u></u>;<br>
- }<br>
};<br>
<br>
/// \brief Generic metadata node.<br>
@@ -279,24 +697,59 @@ protected:<br>
/// TODO: Make uniquing opt-out (status: mandatory, sometimes dropped).<br>
/// TODO: Drop support for RAUW.<br>
class GenericMDNode : public MDNode {<br>
+ friend class Metadata;<br>
friend class MDNode;<br>
friend class LLVMContextImpl;<br>
+ friend class ReplaceableMetadataImpl;<br>
<br>
- unsigned Hash;<br>
+ /// \brief Support RAUW as long as one of its arguments is replaceable.<br>
+ ///<br>
+ /// If an operand is an \a MDNodeFwdDecl (or a replaceable \a GenericMDNode),<br>
+ /// support RAUW to support uniquing as forward declarations are resolved.<br>
+ /// As soon as operands have been resolved, drop support.<br>
+ ///<br>
+ /// FIXME: Save memory by storing this in a pointer union with the<br>
+ /// LLVMContext, and adding an LLVMContext reference to RMI.<br>
+ std::unique_ptr<<u></u>ReplaceableMetadataImpl> ReplaceableUses;<br>
<br>
- GenericMDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)<br>
- : MDNode(C, GenericMDNodeVal, Vals, isFunctionLocal), Hash(0) {}<br>
+ GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals);<br>
~GenericMDNode();<br>
<br>
- void dropAllReferences();<br>
+ void setHash(unsigned Hash) { MDNodeSubclassData = Hash; }<br>
<br>
public:<br>
/// \brief Get the hash, if any.<br>
- unsigned getHash() const { return Hash; }<br>
+ unsigned getHash() const { return MDNodeSubclassData; }<br>
<br>
- static bool classof(const Value *V) {<br>
- return V->getValueID() == GenericMDNodeVal;<br>
+ static bool classof(const Metadata *MD) {<br>
+ return MD->getMetadataID() == GenericMDNodeKind;<br>
}<br>
+<br>
+ /// \brief Check whether any operands are forward declarations.<br>
+ ///<br>
+ /// Returns \c true as long as any operands (or their operands, etc.) are \a<br>
+ /// MDNodeFwdDecl.<br>
+ ///<br>
+ /// As forward declarations are resolved, their containers should get<br>
+ /// resolved automatically. However, if this (or one of its operands) is<br>
+ /// involved in a cycle, \a resolveCycles() needs to be called explicitly.<br>
+ bool isResolved() const { return !ReplaceableUses; }<br>
+<br>
+ /// \brief Resolve cycles.<br>
+ ///<br>
+ /// Once all forward declarations have been resolved, force cycles to be<br>
+ /// resolved.<br>
+ ///<br>
+ /// \pre No operands (or operands' operands, etc.) are \a MDNodeFwdDecl.<br>
+ void resolveCycles();<br>
+<br>
+private:<br>
+ void handleChangedOperand(void *Ref, Metadata *New);<br>
+<br>
+ bool hasUnresolvedOperands() const { return SubclassData32; }<br>
+ void incrementUnresolvedOperands() { ++SubclassData32; }<br>
+ void decrementUnresolvedOperands() { --SubclassData32; }<br>
+ void resolve();<br>
};<br>
<br>
/// \brief Forward declaration of metadata.<br>
@@ -304,17 +757,21 @@ public:<br>
/// Forward declaration of metadata, in the form of a metadata node. Unlike \a<br>
/// GenericMDNode, this class has support for RAUW and is suitable for forward<br>
/// references.<br>
-class MDNodeFwdDecl : public MDNode {<br>
+class MDNodeFwdDecl : public MDNode, ReplaceableMetadataImpl {<br>
+ friend class Metadata;<br>
friend class MDNode;<br>
+ friend class ReplaceableMetadataImpl;<br>
<br>
- MDNodeFwdDecl(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)<br>
- : MDNode(C, MDNodeFwdDeclVal, Vals, isFunctionLocal) {}<br>
+ MDNodeFwdDecl(LLVMContext &C, ArrayRef<Metadata *> Vals)<br>
+ : MDNode(C, MDNodeFwdDeclKind, Vals) {}<br>
~MDNodeFwdDecl() {}<br>
<br>
public:<br>
- static bool classof(const Value *V) {<br>
- return V->getValueID() == MDNodeFwdDeclVal;<br>
+ static bool classof(const Metadata *MD) {<br>
+ return MD->getMetadataID() == MDNodeFwdDeclKind;<br>
}<br>
+<br>
+ using ReplaceableMetadataImpl::<u></u>replaceAllUsesWith;<br>
};<br>
<br>
//===-------------------------<u></u>------------------------------<u></u>---------------===//<br>
@@ -333,7 +790,7 @@ class NamedMDNode : public ilist_node<Na<br>
<br>
std::string Name;<br>
Module *Parent;<br>
- void *Operands; // SmallVector<TrackingVH<MDNode><u></u>, 4><br>
+ void *Operands; // SmallVector<TrackingMDRef, 4><br>
<br>
void setParent(Module *M) { Parent = M; }<br>
<br>
<br>
Added: llvm/trunk/include/llvm/IR/<u></u>MetadataTracking.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/MetadataTracking.h?rev=223802&view=auto" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/MetadataTracking.h?<u></u>rev=223802&view=auto</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>MetadataTracking.h (added)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>MetadataTracking.h Tue Dec 9 12:38:53 2014<br>
@@ -0,0 +1,99 @@<br>
+//===- llvm/IR/MetadataTracking.h - Metadata tracking ---------------------===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<br>
+//<br>
+// Low-level functions to enable tracking of metadata that could RAUW.<br>
+//<br>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<br>
+<br>
+#ifndef LLVM_IR_METADATATRACKING_H<br>
+#define LLVM_IR_METADATATRACKING_H<br>
+<br>
+#include "llvm/ADT/PointerUnion.h"<br>
+#include "llvm/Support/Casting.h"<br>
+#include <type_traits><br>
+<br>
+namespace llvm {<br>
+<br>
+class Metadata;<br>
+class MetadataAsValue;<br>
+<br>
+/// \brief API for tracking metadata references through RAUW and deletion.<br>
+///<br>
+/// Shared API for updating \a Metadata pointers in subclasses that support<br>
+/// RAUW.<br>
+///<br>
+/// This API is not meant to be used directly. See \a TrackingMDRef for a<br>
+/// user-friendly tracking reference.<br>
+class MetadataTracking {<br>
+public:<br>
+ /// \brief Track the reference to metadata.<br>
+ ///<br>
+ /// Register \c MD with \c *MD, if the subclass supports tracking. If \c *MD<br>
+ /// gets RAUW'ed, \c MD will be updated to the new address. If \c *MD gets<br>
+ /// deleted, \c MD will be set to \c nullptr.<br>
+ ///<br>
+ /// If tracking isn't supported, \c *MD will not change.<br>
+ ///<br>
+ /// \return true iff tracking is supported by \c MD.<br>
+ static bool track(Metadata *&MD) {<br>
+ return track(&MD, *MD, static_cast<Metadata *>(nullptr));<br>
+ }<br>
+<br>
+ /// \brief Track the reference to metadata for \a Metadata.<br>
+ ///<br>
+ /// As \a track(Metadata*&), but with support for calling back to \c Owner to<br>
+ /// tell it that its operand changed. This could trigger \c Owner being<br>
+ /// re-uniqued.<br>
+ static bool track(void *Ref, Metadata &MD, Metadata &Owner) {<br>
+ return track(Ref, MD, &Owner);<br>
+ }<br>
+<br>
+ /// \brief Track the reference to metadata for \a MetadataAsValue.<br>
+ ///<br>
+ /// As \a track(Metadata*&), but with support for calling back to \c Owner to<br>
+ /// tell it that its operand changed. This could trigger \c Owner being<br>
+ /// re-uniqued.<br>
+ static bool track(void *Ref, Metadata &MD, MetadataAsValue &Owner) {<br>
+ return track(Ref, MD, &Owner);<br>
+ }<br>
+<br>
+ /// \brief Stop tracking a reference to metadata.<br>
+ ///<br>
+ /// Stops \c *MD from tracking \c MD.<br>
+ static void untrack(Metadata *&MD) { untrack(&MD, *MD); }<br>
+ static void untrack(void *Ref, Metadata &MD);<br>
+<br>
+ /// \brief Move tracking from one reference to another.<br>
+ ///<br>
+ /// Semantically equivalent to \c untrack(MD) followed by \c track(New),<br>
+ /// except that ownership callbacks are maintained.<br>
+ ///<br>
+ /// Note: it is an error if \c *MD does not equal \c New.<br>
+ ///<br>
+ /// \return true iff tracking is supported by \c MD.<br>
+ static bool retrack(Metadata *&MD, Metadata *&New) {<br>
+ return retrack(&MD, *MD, &New);<br>
+ }<br>
+ static bool retrack(void *Ref, Metadata &MD, void *New);<br>
+<br>
+ /// \brief Check whether metadata is replaceable.<br>
+ static bool isReplaceable(const Metadata &MD);<br>
+<br>
+ typedef PointerUnion<MetadataAsValue *, Metadata *> OwnerTy;<br>
+<br>
+private:<br>
+ /// \brief Track a reference to metadata for an owner.<br>
+ ///<br>
+ /// Generalized version of tracking.<br>
+ static bool track(void *Ref, Metadata &MD, OwnerTy Owner);<br>
+};<br>
+<br>
+} // end namespace llvm<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>Module.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=223802&r1=223801&r2=223802&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/Module.h?rev=223802&<u></u>r1=223801&r2=223802&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>Module.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>Module.h Tue Dec 9 12:38:53 2014<br>
@@ -188,16 +188,16 @@ public:<br>
ModFlagBehaviorLastVal = AppendUnique<br>
};<br>
<br>
- /// Checks if Value represents a valid ModFlagBehavior, and stores the<br>
+ /// Checks if Metadata represents a valid ModFlagBehavior, and stores the<br>
/// converted result in MFB.<br>
- static bool isValidModFlagBehavior(Value *V, ModFlagBehavior &MFB);<br>
+ static bool isValidModFlagBehavior(<u></u>Metadata *MD, ModFlagBehavior &MFB);<br>
<br>
struct ModuleFlagEntry {<br>
ModFlagBehavior Behavior;<br>
MDString *Key;<br>
- Value *Val;<br>
- ModuleFlagEntry(<u></u>ModFlagBehavior B, MDString *K, Value *V)<br>
- : Behavior(B), Key(K), Val(V) {}<br>
+ Metadata *Val;<br>
+ ModuleFlagEntry(<u></u>ModFlagBehavior B, MDString *K, Metadata *V)<br>
+ : Behavior(B), Key(K), Val(V) {}<br>
};<br>
<br>
/// @}<br>
@@ -442,7 +442,7 @@ public:<br></blockquote></div>