コード例 #1
0
ファイル: CloneModule.cpp プロジェクト: mapu/llvm
Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
  // First off, we need to create the new module.
  Module *New = new Module(M->getModuleIdentifier(), M->getContext());
  New->setDataLayout(M->getDataLayout());
  New->setTargetTriple(M->getTargetTriple());
  New->setModuleInlineAsm(M->getModuleInlineAsm());
   
  // Loop over all of the global variables, making corresponding globals in the
  // new module.  Here we add them to the VMap and to the new Module.  We
  // don't worry about attributes or initializers, they will come later.
  //
  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I) {
    GlobalVariable *GV = new GlobalVariable(*New, 
                                            I->getType()->getElementType(),
                                            I->isConstant(), I->getLinkage(),
                                            (Constant*) 0, I->getName(),
                                            (GlobalVariable*) 0,
                                            I->getThreadLocalMode(),
                                            I->getType()->getAddressSpace());
    GV->copyAttributesFrom(I);
    VMap[I] = GV;
  }

  // Loop over the functions in the module, making external functions as before
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
    Function *NF =
      Function::Create(cast<FunctionType>(I->getType()->getElementType()),
                       I->getLinkage(), I->getName(), New);
    NF->copyAttributesFrom(I);
    VMap[I] = NF;
  }

  // Loop over the aliases in the module
  for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
       I != E; ++I) {
    GlobalAlias *GA = new GlobalAlias(I->getType(), I->getLinkage(),
                                      I->getName(), NULL, New);
    GA->copyAttributesFrom(I);
    VMap[I] = GA;
  }
  
  // Now that all of the things that global variable initializer can refer to
  // have been created, loop through and copy the global variable referrers
  // over...  We also set the attributes on the global now.
  //
  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I) {
    GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
    if (I->hasInitializer())
      GV->setInitializer(MapValue(I->getInitializer(), VMap));
  }

  // Similarly, copy over function bodies now...
  //
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
    Function *F = cast<Function>(VMap[I]);
    if (!I->isDeclaration()) {
      Function::arg_iterator DestI = F->arg_begin();
      for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end();
           ++J) {
        DestI->setName(J->getName());
        VMap[J] = DestI++;
      }

      SmallVector<ReturnInst*, 8> Returns;  // Ignore returns cloned.
      CloneFunctionInto(F, I, VMap, /*ModuleLevelChanges=*/true, Returns);
    }
  }

  // And aliases
  for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
       I != E; ++I) {
    GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
    if (const Constant *C = I->getAliasee())
      GA->setAliasee(MapValue(C, VMap));
  }

  // And named metadata....
  for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
         E = M->named_metadata_end(); I != E; ++I) {
    const NamedMDNode &NMD = *I;
    NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
    for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
      NewNMD->addOperand(MapValue(NMD.getOperand(i), VMap));
  }

  return New;
}
コード例 #2
0
void
link(llvm::Module *krn, const llvm::Module *lib)
{
    assert(krn);
    assert(lib);
    ValueToValueMapTy vvm;
    std::list<llvm::StringRef> declared;

    // Inspect the kernel, find undefined functions
    llvm::Module::iterator fi,fe;
    for (fi=krn->begin(), fe=krn->end();
         fi != fe;
         fi++) {
        if ((*fi).isDeclaration()) {
            DB_PRINT("%s is not defined\n", fi->getName().data());
            declared.push_back(fi->getName());
            continue;
        }

        // Find all functions the kernel source calls
        // TODO: is there no direct way?
        find_called_functions(fi, declared);
    }
    declared.sort(stringref_cmp);
    declared.unique(stringref_equal);

    // copy all the globals from lib to krn.
    // it probably is faster to just copy them all, than to inspect
    // both krn and lib to find which actually are used.
    DB_PRINT("cloning the global variables:\n");
    llvm::Module::const_global_iterator gi,ge;
    for (gi=lib->global_begin(), ge=lib->global_end();
         gi != ge;
         gi++) {
        DB_PRINT(" %s\n", gi->getName().data());
        GlobalVariable *GV=new GlobalVariable(*krn,
                                              gi->getType()->getElementType(),
                                              gi->isConstant(),
                                              gi->getLinkage(),
                                              (Constant*) 0, gi->getName(),
                                              (GlobalVariable*) 0,
                                              gi->getThreadLocalMode(),
                                              gi->getType()->getAddressSpace());
        GV->copyAttributesFrom(gi);
        vvm[gi]=GV;
    }

    // For each undefined function in krn, clone it from the lib to the krn module,
    // if found in lib
    std::list<llvm::StringRef>::iterator di,de;
    for (di=declared.begin(), de=declared.end();
         di != de;
         di++) {
        copy_func_callgraph( *di, lib, krn, vvm);
    }

    // copy any aliases to krn
    DB_PRINT("cloning the aliases:\n");
    llvm::Module::const_alias_iterator ai, ae;
    for (ai = lib->alias_begin(), ae = lib->alias_end();
         ai != ae;
         ai++) {
        DB_PRINT(" %s\n", ai->getName().data());
        GlobalAlias *GA =
#if (defined LLVM_3_2 || defined LLVM_3_3 || defined LLVM_3_4)
            new GlobalAlias(ai->getType(), ai->getLinkage(),
                            ai->getName(), NULL, krn);
#elif (defined LLVM_OLDER_THAN_3_7)
            GlobalAlias::create(ai->getType(),
                                ai->getType()->getAddressSpace(),
                                ai->getLinkage(), ai->getName(), NULL, krn);
#else
            GlobalAlias::create(ai->getType(),
                                ai->getLinkage(), ai->getName(), NULL, krn);
#endif

        GA->copyAttributesFrom(ai);
        vvm[ai]=GA;
    }

    // initialize the globals that were copied
    for (gi=lib->global_begin(), ge=lib->global_end();
         gi != ge;
         gi++) {
        GlobalVariable *GV=cast<GlobalVariable>(vvm[gi]);
        if (gi->hasInitializer())
            GV->setInitializer(MapValue(gi->getInitializer(), vvm));
    }

    // copy metadata
    DB_PRINT("cloning metadata:\n");
    llvm::Module::const_named_metadata_iterator mi,me;
    for (mi=lib->named_metadata_begin(), me=lib->named_metadata_end();
         mi != me;
         mi++) {
        const NamedMDNode &NMD=*mi;
        DB_PRINT(" %s:\n", NMD.getName().data());
        NamedMDNode *NewNMD=krn->getOrInsertNamedMetadata(NMD.getName());
        for (unsigned i=0, e=NMD.getNumOperands(); i != e; ++i)
#ifdef LLVM_OLDER_THAN_3_6
            NewNMD->addOperand(MapValue(NMD.getOperand(i), vvm));
#else
            NewNMD->addOperand(MapMetadata(NMD.getOperand(i), vvm));
#endif
    }
}