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

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172498 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2013-01-15 01:22:53 +00:00
parent 096d617796
commit 8dd938ed17
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 (or more) metadata with the same ID. The supported behaviors are
described below. described below.
- The second element is a metadata string that is a unique ID for the - 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. - The third element is the value of the flag.
When two (or more) modules are merged together, the resulting When two (or more) modules are merged together, the resulting
``llvm.module.flags`` metadata is the union of the modules' ``llvm.module.flags`` metadata is the union of the modules' flags. That is, for
``llvm.module.flags`` metadata. The only exception being a flag with the each unique metadata ID string, there will be exactly one entry in the merged
*Override* behavior, which may override another flag's value (see modules ``llvm.module.flags`` metadata table, and the value for that entry will
below). 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: The following behaviors are supported:
@ -2482,25 +2484,33 @@ The following behaviors are supported:
* - 1 * - 1
- **Error** - **Error**
Emits an error if two values disagree. It is an error to have an Emits an error if two values disagree, otherwise the resulting value
ID with both an Error and a Warning behavior. is that of the operands.
* - 2 * - 2
- **Warning** - **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 * - 3
- **Require** - **Require**
Emits an error when the specified value is not present or doesn't Adds a requirement that another module flag be present and have a
have the specified value. It is an error for two (or more) specified value after linking is performed. The value must be a
``llvm.module.flags`` with the same ID to have the Require behavior metadata pair, where the first element of the pair is the ID of the
but different values. There may be multiple Require flags per ID. 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 * - 4
- **Override** - **Override**
Uses the specified value if the two values disagree. It is an Uses the specified value, regardless of the behavior or value of the
error for two (or more) ``llvm.module.flags`` with the same ID other module. If both modules specify **Override**, but the values
to have the Override behavior but different 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: 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 - 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 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 - Metadata ``!2`` has the ID ``!"qux"`` and the value '42'. The
behavior if two or more ``!"qux"`` flags are seen is to emit a 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 } metadata !{ metadata !"foo", i32 1 }
The behavior is to emit an error if the ``llvm.module.flags`` does The behavior is to emit an error if the ``llvm.module.flags`` does not
not contain a flag with the ID ``!"foo"`` that has the value '1'. If contain a flag with the ID ``!"foo"`` that has the value '1' after linking is
two or more ``!"qux"`` flags exist, then they must have the same performed.
value or an error will be issued.
Objective-C Garbage Collection Module Flags Metadata Objective-C Garbage Collection Module Flags Metadata
---------------------------------------------------- ----------------------------------------------------

View File

@ -200,6 +200,8 @@ namespace {
E = M.named_metadata_end(); I != E; ++I) E = M.named_metadata_end(); I != E; ++I)
visitNamedMDNode(*I); visitNamedMDNode(*I);
visitModuleFlags(M);
// If the module is broken, abort at this time. // If the module is broken, abort at this time.
return abortIfBroken(); return abortIfBroken();
} }
@ -240,6 +242,8 @@ namespace {
void visitGlobalAlias(GlobalAlias &GA); void visitGlobalAlias(GlobalAlias &GA);
void visitNamedMDNode(NamedMDNode &NMD); void visitNamedMDNode(NamedMDNode &NMD);
void visitMDNode(MDNode &MD, Function *F); void visitMDNode(MDNode &MD, Function *F);
void visitModuleFlags(Module &M);
void visitModuleFlag(MDNode *Op, SmallSetVector<MDString*, 16> &SeenIDs);
void visitFunction(Function &F); void visitFunction(Function &F);
void visitBasicBlock(BasicBlock &BB); void visitBasicBlock(BasicBlock &BB);
using InstVisitor<Verifier>::visit; 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 // VerifyParameterAttrs - Check the given attributes for an argument or return
// value of the specified type. The value V is printed in error messages. // value of the specified type. The value V is printed in error messages.
void Verifier::VerifyParameterAttrs(Attribute Attrs, Type *Ty, 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 }