view gen/passes/StripMetaData.cpp @ 1317:4099548c80e0

Allocate objects on the stack if they (a) don't have a destructor, and (b) don't override the delete operator (on top of the regular conditions for stack allocation that also apply to arrays, structs, etc.). The "no destructor" clause is not strictly necessary, but calling them at the right time would be tricky to say the least; it would involve, among other things, "manually" inserting a try-finally block around anything that might throw exceptions not caught in the current function. Note: objects with custom new operators are automatically ignored because they don't use the regular allocation runtime call, so there's no need to pay special attention to them.
author Frits van Bommel <fvbommel wxs.nl>
date Sat, 09 May 2009 00:50:15 +0200
parents 6c8af78364f5
children c21a6654cce2
line wrap: on
line source

//===- 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