mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-25 00:29:20 +00:00
[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:
parent
096d617796
commit
8dd938ed17
@ -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
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
@ -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,
|
||||||
|
37
test/Verifier/module-flags-1.ll
Normal file
37
test/Verifier/module-flags-1.ll
Normal 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 }
|
Loading…
Reference in New Issue
Block a user