[IR] Add verifier support for llvm.module.flags.

- Also, update the LangRef documentation on module flags to match the
   implementation.

llvm-svn: 172498
This commit is contained in:
Daniel Dunbar 2013-01-15 01:22:53 +00:00
parent 5f15a35114
commit 25c4b5718b
3 changed files with 123 additions and 20 deletions

View File

@ -2462,14 +2462,16 @@ Each triplet has the following form:
(or more) metadata with the same ID. The supported behaviors are
described below.
- The second element is a metadata string that is a unique ID for the
metadata. How each ID is interpreted is documented below.
metadata. Each module may only have one flag entry for each unique ID (not
including entries with the **Require** behavior).
- The third element is the value of the flag.
When two (or more) modules are merged together, the resulting
``llvm.module.flags`` metadata is the union of the modules'
``llvm.module.flags`` metadata. The only exception being a flag with the
*Override* behavior, which may override another flag's value (see
below).
``llvm.module.flags`` metadata is the union of the modules' flags. That is, for
each unique metadata ID string, there will be exactly one entry in the merged
modules ``llvm.module.flags`` metadata table, and the value for that entry will
be determined by the merge behavior flag, as described below. The only exception
is that entries with the *Require* behavior are always preserved.
The following behaviors are supported:
@ -2482,25 +2484,33 @@ The following behaviors are supported:
* - 1
- **Error**
Emits an error if two values disagree. It is an error to have an
ID with both an Error and a Warning behavior.
Emits an error if two values disagree, otherwise the resulting value
is that of the operands.
* - 2
- **Warning**
Emits a warning if two values disagree.
Emits a warning if two values disagree. The result value will be the
operand for the flag from the first module being linked.
* - 3
- **Require**
Emits an error when the specified value is not present or doesn't
have the specified value. It is an error for two (or more)
``llvm.module.flags`` with the same ID to have the Require behavior
but different values. There may be multiple Require flags per ID.
Adds a requirement that another module flag be present and have a
specified value after linking is performed. The value must be a
metadata pair, where the first element of the pair is the ID of the
module flag to be restricted, and the second element of the pair is
the value the module flag should be restricted to. This behavior can
be used to restrict the allowable results (via triggering of an
error) of linking IDs with the **Override** behavior.
* - 4
- **Override**
Uses the specified value if the two values disagree. It is an
error for two (or more) ``llvm.module.flags`` with the same ID
to have the Override behavior but different values.
Uses the specified value, regardless of the behavior or value of the
other module. If both modules specify **Override**, but the values
differ, an error will be emitted.
It is an error for a particular unique flag ID to have multiple behaviors,
except in the case of **Require** (which adds restrictions on another metadata
value) or **Override**.
An example of module flags:
@ -2522,7 +2532,7 @@ An example of module flags:
- Metadata ``!1`` has the ID ``!"bar"`` and the value '37'. The
behavior if two or more ``!"bar"`` flags are seen is to use the value
'37' if their values are not equal.
'37'.
- Metadata ``!2`` has the ID ``!"qux"`` and the value '42'. The
behavior if two or more ``!"qux"`` flags are seen is to emit a
@ -2534,10 +2544,9 @@ An example of module flags:
metadata !{ metadata !"foo", i32 1 }
The behavior is to emit an error if the ``llvm.module.flags`` does
not contain a flag with the ID ``!"foo"`` that has the value '1'. If
two or more ``!"qux"`` flags exist, then they must have the same
value or an error will be issued.
The behavior is to emit an error if the ``llvm.module.flags`` does not
contain a flag with the ID ``!"foo"`` that has the value '1' after linking is
performed.
Objective-C Garbage Collection Module Flags Metadata
----------------------------------------------------

View File

@ -200,6 +200,8 @@ namespace {
E = M.named_metadata_end(); I != E; ++I)
visitNamedMDNode(*I);
visitModuleFlags(M);
// If the module is broken, abort at this time.
return abortIfBroken();
}
@ -240,6 +242,8 @@ namespace {
void visitGlobalAlias(GlobalAlias &GA);
void visitNamedMDNode(NamedMDNode &NMD);
void visitMDNode(MDNode &MD, Function *F);
void visitModuleFlags(Module &M);
void visitModuleFlag(MDNode *Op, SmallSetVector<MDString*, 16> &SeenIDs);
void visitFunction(Function &F);
void visitBasicBlock(BasicBlock &BB);
using InstVisitor<Verifier>::visit;
@ -521,6 +525,59 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) {
}
}
void Verifier::visitModuleFlags(Module &M) {
const NamedMDNode *Flags = M.getModuleFlagsMetadata();
if (!Flags) return;
// Scan each flag.
SmallSetVector<MDString*, 16> SeenIDs;
for (unsigned I = 0, E = Flags->getNumOperands(); I != E; ++I) {
visitModuleFlag(Flags->getOperand(I), SeenIDs);
}
}
void Verifier::visitModuleFlag(MDNode *Op,
SmallSetVector<MDString*, 16> &SeenIDs) {
// Each module flag should have three arguments, the merge behavior (a
// constant int), the flag ID (an MDString), and the value.
Assert1(Op->getNumOperands() == 3,
"incorrect number of operands in module flag", Op);
ConstantInt *Behavior = dyn_cast<ConstantInt>(Op->getOperand(0));
MDString *ID = dyn_cast<MDString>(Op->getOperand(1));
Assert1(Behavior,
"invalid behavior operand in module flag (expected constant integer)",
Op->getOperand(0));
unsigned BehaviorValue = Behavior->getZExtValue();
Assert1((Module::Error <= BehaviorValue &&
BehaviorValue <= Module::Override),
"invalid behavior operand in module flag (unexpected constant)",
Op->getOperand(0));
Assert1(ID,
"invalid ID operand in module flag (expected metadata string)",
Op->getOperand(1));
// Unless this is a "requires" flag, check the ID is unique.
if (BehaviorValue != Module::Require) {
Assert1(SeenIDs.insert(ID),
"module flag identifiers must be unique (or of 'require' type)",
ID);
}
// If this is a "requires" flag, sanity check the value.
if (BehaviorValue == Module::Require) {
// The value should itself be an MDNode with two operands, a flag ID (an
// MDString), and a value.
MDNode *Value = dyn_cast<MDNode>(Op->getOperand(2));
Assert1(Value && Value->getNumOperands() == 2,
"invalid value for 'require' module flag (expected metadata pair)",
Op->getOperand(2));
Assert1(isa<MDString>(Value->getOperand(0)),
("invalid value for 'require' module flag "
"(first value operand should be a string)"),
Value->getOperand(0));
}
}
// VerifyParameterAttrs - Check the given attributes for an argument or return
// value of the specified type. The value V is printed in error messages.
void Verifier::VerifyParameterAttrs(Attribute Attrs, Type *Ty,

View File

@ -0,0 +1,37 @@
; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
; Check that module flags are structurally correct.
;
; CHECK: incorrect number of operands in module flag
; CHECK: metadata !0
!0 = metadata !{ i32 1 }
; CHECK: invalid behavior operand in module flag (expected constant integer)
; CHECK: metadata !"foo"
!1 = metadata !{ metadata !"foo", metadata !"foo", i32 42 }
; CHECK: invalid behavior operand in module flag (unexpected constant)
; CHECK: i32 999
!2 = metadata !{ i32 999, metadata !"foo", i32 43 }
; CHECK: invalid ID operand in module flag (expected metadata string)
; CHECK: i32 1
!3 = metadata !{ i32 1, i32 1, i32 44 }
; CHECK: invalid value for 'require' module flag (expected metadata pair)
; CHECK: i32 45
!4 = metadata !{ i32 3, metadata !"bla", i32 45 }
; CHECK: invalid value for 'require' module flag (expected metadata pair)
; CHECK: metadata !
!5 = metadata !{ i32 3, metadata !"bla", metadata !{ i32 46 } }
; CHECK: invalid value for 'require' module flag (first value operand should be a string)
; CHECK: i32 47
!6 = metadata !{ i32 3, metadata !"bla", metadata !{ i32 47, i32 48 } }
; Check that module flags only have unique IDs.
;
; CHECK: module flag identifiers must be unique (or of 'require' type)
!7 = metadata !{ i32 1, metadata !"foo", i32 49 }
!8 = metadata !{ i32 2, metadata !"foo", i32 50 }
; CHECK-NOT: module flag identifiers must be unique
!9 = metadata !{ i32 2, metadata !"bar", i32 51 }
!10 = metadata !{ i32 3, metadata !"bar", i32 51 }
!llvm.module.flags = !{
!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10 }