Mercurial > projects > ldc
diff gen/passes/StripMetaData.cpp @ 1287:6c8af78364f5
There's an issue with LLVM metadata support; it triggers an assert when trying
to generate asm for code with metadata globals.
This new pass is used as a workaround: it strips metadata from the module before
it reaches the code generator.
Obviously, this is disabled if LLVM doesn't support metadata.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sat, 02 May 2009 12:19:43 +0200 |
parents | |
children | c21a6654cce2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/passes/StripMetaData.cpp Sat May 02 12:19:43 2009 +0200 @@ -0,0 +1,85 @@ +//===- StripMetaData - Strips D-specific metadata -------------------------===// +// +// The LLVM D Compiler +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// There's an issue with the new LLVM metadata support; an assertion fires when +// trying to generate asm for metadata globals. +// +// This pass is a workaround; it deletes the metadata LDC generates so the code +// generator doesn't see it. +// Obviously, this should only run after all passes that make use of that +// metadata or they won't work. +// +//===----------------------------------------------------------------------===// + +#include "gen/metadata.h" + +// This pass isn't needed without metadata, so #ifdef it out entirely if the +// LLVM version in use doesn't support it. +#ifdef USE_METADATA + + +#define DEBUG_TYPE "strip-metadata" + +#include "Passes.h" + +#include "llvm/Pass.h" +#include "llvm/Module.h" +#include "llvm/Constants.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +using namespace llvm; + +STATISTIC(NumDeleted, "Number of metadata globals deleted"); + +//===----------------------------------------------------------------------===// +// StripMetaData Pass Implementation +//===----------------------------------------------------------------------===// + +namespace { + /// This pass optimizes library functions from the D runtime as used by LDC. + /// + class VISIBILITY_HIDDEN StripMetaData : public ModulePass { + public: + static char ID; // Pass identification + StripMetaData() : ModulePass(&ID) {} + + bool runOnModule(Module &M); + }; + char StripMetaData::ID = 0; +} // end anonymous namespace. + +static RegisterPass<StripMetaData> +X("strip-metadata", "Delete D-specific metadata"); + +// Public interface to the pass. +ModulePass *createStripMetaData() { + return new StripMetaData(); +} + +/// runOnFunction - Top level algorithm. +/// +bool StripMetaData::runOnModule(Module &M) { + bool Changed = false; + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E;) { + GlobalVariable* G = I++; + if (G->getNameLen() >= 9 && !strncmp(G->getNameStart(), "llvm.ldc.", 9)) { + assert(G->hasInitializer() && isa<MDNode>(G->getInitializer()) + && "Not a metadata global?"); + Changed = true; + NumDeleted++; + DEBUG(DOUT << "Deleting " << *G << '\n'); + G->eraseFromParent(); + } + } + return Changed; +} + + +#endif //USE_METADATA