[llvm] r199354 - Reapply r194218 with fix:

Bill Wendling isanbard at gmail.com
Wed Jan 15 22:29:37 PST 2014


Author: void
Date: Thu Jan 16 00:29:36 2014
New Revision: 199354

URL: http://llvm.org/viewvc/llvm-project?rev=199354&view=rev
Log:
Reapply r194218 with fix:

Move copying of global initializers below the cloning of functions.

The BlockAddress doesn't have access to the correct basic blocks until the
functions have been cloned. This causes the BlockAddress to point to the old
values. Just wait until the functions have been cloned before copying the
initializers.
PR13163

Added:
    llvm/trunk/unittests/Linker/
    llvm/trunk/unittests/Linker/CMakeLists.txt
    llvm/trunk/unittests/Linker/LinkModulesTest.cpp
    llvm/trunk/unittests/Linker/Makefile
      - copied, changed from r199346, llvm/trunk/unittests/Makefile
Modified:
    llvm/trunk/lib/Linker/LinkModules.cpp
    llvm/trunk/unittests/Makefile

Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=199354&r1=199353&r2=199354&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Thu Jan 16 00:29:36 2014
@@ -1249,10 +1249,6 @@ bool ModuleLinker::run() {
   for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i)
     linkAppendingVarInit(AppendingVars[i]);
   
-  // Update the initializers in the DstM module now that all globals that may
-  // be referenced are in DstM.
-  linkGlobalInits();
-
   // Link in the function bodies that are defined in the source module into
   // DstM.
   for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) {
@@ -1290,6 +1286,10 @@ bool ModuleLinker::run() {
   if (linkModuleFlagsMetadata())
     return true;
 
+  // Update the initializers in the DstM module now that all globals that may
+  // be referenced are in DstM.
+  linkGlobalInits();
+
   // Process vector of lazily linked in functions.
   bool LinkedInAnyFunctions;
   do {

Added: llvm/trunk/unittests/Linker/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Linker/CMakeLists.txt?rev=199354&view=auto
==============================================================================
--- llvm/trunk/unittests/Linker/CMakeLists.txt (added)
+++ llvm/trunk/unittests/Linker/CMakeLists.txt Thu Jan 16 00:29:36 2014
@@ -0,0 +1,12 @@
+set(LLVM_LINK_COMPONENTS
+  core
+  linker
+  )
+
+set(LinkerSources
+  LinkModulesTest.cpp
+  )
+
+add_llvm_unittest(LinkerTests
+  ${LinkerSources}
+  )

Added: llvm/trunk/unittests/Linker/LinkModulesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Linker/LinkModulesTest.cpp?rev=199354&view=auto
==============================================================================
--- llvm/trunk/unittests/Linker/LinkModulesTest.cpp (added)
+++ llvm/trunk/unittests/Linker/LinkModulesTest.cpp Thu Jan 16 00:29:36 2014
@@ -0,0 +1,165 @@
+//===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Linker.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class LinkModuleTest : public testing::Test {
+protected:
+  virtual void SetUp() {
+    LLVMContext &Ctx = getGlobalContext();
+    M.reset(new Module("MyModule", Ctx));
+    FunctionType *FTy = FunctionType::get(Type::getInt8PtrTy(Ctx),
+                                          Type::getInt32Ty(Ctx),
+                                          false /*=isVarArg*/);
+    F = Function::Create(FTy, Function::ExternalLinkage, "ba_func", M.get());
+    F->setCallingConv(CallingConv::C);
+
+    EntryBB = BasicBlock::Create(Ctx, "entry", F);
+    SwitchCase1BB = BasicBlock::Create(Ctx, "switch.case.1", F);
+    SwitchCase2BB = BasicBlock::Create(Ctx, "switch.case.2", F);
+    ExitBB = BasicBlock::Create(Ctx, "exit", F);
+
+    ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
+
+    GV = new GlobalVariable(*M.get(), AT, false /*=isConstant*/,
+                            GlobalValue::InternalLinkage,
+                            0, "switch.bas");
+
+
+    // Global Initializer
+    std::vector<Constant*> Init;
+    Constant *SwitchCase1BA = BlockAddress::get(SwitchCase1BB);
+    Init.push_back(SwitchCase1BA);
+
+    Constant *SwitchCase2BA = BlockAddress::get(SwitchCase2BB);
+    Init.push_back(SwitchCase2BA);
+
+    ConstantInt *One = ConstantInt::get(Type::getInt32Ty(Ctx), 1);
+    Constant *OnePtr = ConstantExpr::getCast(Instruction::IntToPtr,
+                                             One, Type::getInt8PtrTy(Ctx));
+    Init.push_back(OnePtr);
+
+    GV->setInitializer(ConstantArray::get(AT, Init));
+  }
+
+  virtual void TearDown() {
+    M.reset();
+  }
+
+  OwningPtr<Module> M;
+  Function *F;
+  GlobalVariable *GV;
+  BasicBlock *EntryBB;
+  BasicBlock *SwitchCase1BB;
+  BasicBlock *SwitchCase2BB;
+  BasicBlock *ExitBB;
+};
+
+TEST_F(LinkModuleTest, BlockAddress) {
+  LLVMContext &Ctx = getGlobalContext();
+  IRBuilder<> Builder(EntryBB);
+
+  std::vector<Value*> GEPIndices;
+  GEPIndices.push_back(ConstantInt::get(Type::getInt32Ty(Ctx), 0));
+  GEPIndices.push_back(F->arg_begin());
+
+  Value *GEP = Builder.CreateGEP(GV, GEPIndices, "switch.gep");
+  Value *Load = Builder.CreateLoad(GEP, "switch.load");
+
+  Builder.CreateRet(Load);
+
+  Builder.SetInsertPoint(SwitchCase1BB);
+  Builder.CreateBr(ExitBB);
+
+  Builder.SetInsertPoint(SwitchCase2BB);
+  Builder.CreateBr(ExitBB);
+
+  Builder.SetInsertPoint(ExitBB);
+  Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx)));
+
+  Module *LinkedModule = new Module("MyModuleLinked", getGlobalContext());
+  Linker::LinkModules(LinkedModule, M.get(), Linker::PreserveSource, 0);
+
+  // Delete the original module.
+  M.reset();
+
+  // Check that the global "@switch.bas" is well-formed.
+  const GlobalVariable *LinkedGV = LinkedModule->getNamedGlobal("switch.bas");
+  const Constant *Init = LinkedGV->getInitializer();
+
+  // @switch.bas = internal global [3 x i8*]
+  //   [i8* blockaddress(@ba_func, %switch.case.1),
+  //    i8* blockaddress(@ba_func, %switch.case.2),
+  //    i8* inttoptr (i32 1 to i8*)]
+
+  ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
+  EXPECT_EQ(AT, Init->getType());
+
+  Value *Elem = Init->getOperand(0);
+  ASSERT_TRUE(isa<BlockAddress>(Elem));
+  EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
+            LinkedModule->getFunction("ba_func"));
+  EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
+            LinkedModule->getFunction("ba_func"));
+  
+  Elem = Init->getOperand(1);
+  ASSERT_TRUE(isa<BlockAddress>(Elem));
+  EXPECT_EQ(cast<BlockAddress>(Elem)->getFunction(),
+            LinkedModule->getFunction("ba_func"));
+  EXPECT_EQ(cast<BlockAddress>(Elem)->getBasicBlock()->getParent(),
+            LinkedModule->getFunction("ba_func"));
+
+  delete LinkedModule;
+}
+
+TEST_F(LinkModuleTest, EmptyModule) {
+  LLVMContext &Ctx = getGlobalContext();
+  Module *InternalM = new Module("InternalModule", Ctx);
+  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
+                                        Type::getInt8PtrTy(Ctx),
+                                        false /*=isVarArgs*/);
+
+  F = Function::Create(FTy, Function::InternalLinkage, "bar", InternalM);
+  F->setCallingConv(CallingConv::C);
+
+  BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
+  IRBuilder<> Builder(BB);
+  Builder.CreateRetVoid();
+
+  StructType *STy = StructType::create(Ctx, PointerType::get(FTy, 0));
+
+  GlobalVariable *GV =
+    new GlobalVariable(*InternalM, STy, false /*=isConstant*/,
+                       GlobalValue::InternalLinkage, 0, "g");
+
+  GV->setInitializer(ConstantStruct::get(STy, F));
+
+
+  Module *EmptyM = new Module("EmptyModule1", Ctx);
+  Linker::LinkModules(EmptyM, InternalM, Linker::PreserveSource, 0);
+
+  delete EmptyM;
+  EmptyM = new Module("EmptyModule2", Ctx);
+  Linker::LinkModules(InternalM, EmptyM, Linker::PreserveSource, 0);
+
+  delete EmptyM;
+  delete InternalM;
+}
+
+} // end anonymous namespace

Copied: llvm/trunk/unittests/Linker/Makefile (from r199346, llvm/trunk/unittests/Makefile)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Linker/Makefile?p2=llvm/trunk/unittests/Linker/Makefile&p1=llvm/trunk/unittests/Makefile&r1=199346&r2=199354&rev=199354&view=diff
==============================================================================
--- llvm/trunk/unittests/Makefile (original)
+++ llvm/trunk/unittests/Linker/Makefile Thu Jan 16 00:29:36 2014
@@ -1,4 +1,4 @@
-##===- unittests/Makefile ----------------------------------*- Makefile -*-===##
+##===- unittests/Linker/Makefile ---------------------------*- Makefile -*-===##
 #
 #                     The LLVM Compiler Infrastructure
 #
@@ -7,13 +7,9 @@
 #
 ##===----------------------------------------------------------------------===##
 
-LEVEL = ..
-
-PARALLEL_DIRS = ADT Analysis Bitcode CodeGen DebugInfo \
-		ExecutionEngine IR MC Object Option Support Transforms
+LEVEL = ../..
+TESTNAME = Linker
+LINK_COMPONENTS := core linker
 
 include $(LEVEL)/Makefile.config
 include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
-
-clean::
-	$(Verb) $(RM) -f *Tests

Modified: llvm/trunk/unittests/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Makefile?rev=199354&r1=199353&r2=199354&view=diff
==============================================================================
--- llvm/trunk/unittests/Makefile (original)
+++ llvm/trunk/unittests/Makefile Thu Jan 16 00:29:36 2014
@@ -10,7 +10,7 @@
 LEVEL = ..
 
 PARALLEL_DIRS = ADT Analysis Bitcode CodeGen DebugInfo \
-		ExecutionEngine IR MC Object Option Support Transforms
+		ExecutionEngine IR Linker MC Object Option Support Transforms
 
 include $(LEVEL)/Makefile.config
 include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest





More information about the llvm-commits mailing list