summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-06-27 18:19:56 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-06-27 18:19:56 +0000
commitdad0a645a7b392900c9fb34f11815060d03a2233 (patch)
tree99d27820893e856b1492d86fb612f2a2d147cc99 /llvm/lib/IR/Verifier.cpp
parent3260478c10b56f9ee81cc415c962356b1153cd1c (diff)
downloadbcm5719-llvm-dad0a645a7b392900c9fb34f11815060d03a2233.tar.gz
bcm5719-llvm-dad0a645a7b392900c9fb34f11815060d03a2233.zip
IR: Add COMDATs to the IR
This new IR facility allows us to represent the object-file semantic of a COMDAT group. COMDATs allow us to tie together sections and make the inclusion of one dependent on another. This is required to implement features like MS ABI VFTables and optimizing away certain kinds of initialization in C++. This functionality is only representable in COFF and ELF, Mach-O has no similar mechanism. Differential Revision: http://reviews.llvm.org/D4178 llvm-svn: 211920
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index ad3c29c564e..24f3acb9953 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -107,6 +107,12 @@ struct VerifierSupport {
OS << ' ' << *T;
}
+ void WriteComdat(const Comdat *C) {
+ if (!C)
+ return;
+ OS << *C;
+ }
+
// CheckFailed - A check failed, so print out the condition and the message
// that failed. This provides a nice place to put a breakpoint if you want
// to see why something is not correct.
@@ -138,6 +144,12 @@ struct VerifierSupport {
WriteType(T3);
Broken = true;
}
+
+ void CheckFailed(const Twine &Message, const Comdat *C) {
+ OS << Message.str() << "\n";
+ WriteComdat(C);
+ Broken = true;
+ }
};
class Verifier : public InstVisitor<Verifier>, VerifierSupport {
friend class InstVisitor<Verifier>;
@@ -230,6 +242,9 @@ public:
I != E; ++I)
visitNamedMDNode(*I);
+ for (const StringMapEntry<Comdat> &SMEC : M.getComdatSymbolTable())
+ visitComdat(SMEC.getValue());
+
visitModuleFlags(M);
visitModuleIdents(M);
@@ -246,6 +261,7 @@ private:
const GlobalAlias &A, const Constant &C);
void visitNamedMDNode(const NamedMDNode &NMD);
void visitMDNode(MDNode &MD, Function *F);
+ void visitComdat(const Comdat &C);
void visitModuleIdents(const Module &M);
void visitModuleFlags(const Module &M);
void visitModuleFlag(const MDNode *Op,
@@ -387,6 +403,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
"'common' global must have a zero initializer!", &GV);
Assert1(!GV.isConstant(), "'common' global may not be marked constant!",
&GV);
+ Assert1(!GV.hasComdat(), "'common' global may not be in a Comdat!", &GV);
}
} else {
Assert1(GV.hasExternalLinkage() || GV.hasExternalWeakLinkage(),
@@ -578,6 +595,22 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) {
}
}
+void Verifier::visitComdat(const Comdat &C) {
+ // All Comdat::SelectionKind values other than Comdat::Any require a
+ // GlobalValue with the same name as the Comdat.
+ const GlobalValue *GV = M->getNamedValue(C.getName());
+ if (C.getSelectionKind() != Comdat::Any)
+ Assert1(GV,
+ "comdat selection kind requires a global value with the same name",
+ &C);
+ // The Module is invalid if the GlobalValue has local linkage. Allowing
+ // otherwise opens us up to seeing the underling global value get renamed if
+ // collisions occur.
+ if (GV)
+ Assert1(!GV->hasLocalLinkage(), "comdat global value has local linkage",
+ GV);
+}
+
void Verifier::visitModuleIdents(const Module &M) {
const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident");
if (!Idents)
OpenPOWER on IntegriCloud