Add support for anonymous global variables
MODIFY
llvm_util/llvm2alive.cpp
llvm_util/llvm2alive.cpp
@@ -701,13 +701,34 @@ public:
}
}
+ auto getGlobalVariable = [this](const string &name) -> llvm::GlobalVariable * {
+ auto M = f.getParent();
+ // If name is a numeric value, the result should be manually found
+ const char *chrs = name.data();
+ char *end_ptr;
+ auto numeric_id = strtoul(chrs, &end_ptr, 10);
+
+ if (end_ptr - chrs != name.size())
+ return M->getGlobalVariable(name, true);
+ else {
+ auto itr = M->global_begin(), end = M->global_end();
+ for (; itr != end; ++itr) {
+ if (itr->hasName())
+ continue;
+ if (!numeric_id)
+ return &(*itr);
+ numeric_id--;
+ }
+ return nullptr;
+ }
+ };
+
// If there is a global variable with initializer, put them at init block.
auto &entryName = Fn.getFirstBB().getName();
auto &InitBB = Fn.getBB("__globalvars_init", true);
BB = &InitBB;
- auto M = f.getParent();
for (auto &gvname : gvnamesInSrc) {
- auto gv = M->getGlobalVariable(string(gvname), true);
+ auto gv = getGlobalVariable(string(gvname));
if (!gv) {
// global variable removed or renamed
*out << "ERROR: Unsupported interprocedural transformation\n";
@@ -724,7 +745,7 @@ public:
auto GV = dynamic_cast<GlobalVariable *>(&Fn.getConstant(i));
if (!GV)
continue;
- auto gv = M->getGlobalVariable(GV->getName().substr(1), true);
+ auto gv = getGlobalVariable(GV->getName().substr(1));
if (!gv->isConstant() || !gv->hasInitializer())
continue;
@@ -732,7 +753,7 @@ public:
if (!storedval)
return {};
- stores.emplace(gv->getName(),
+ stores.emplace(GV->getName(),
make_unique<Store>(*GV, *storedval, GV->getAlignment()));
}

MODIFY
llvm_util/utils.cpp
llvm_util/utils.cpp
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include <unordered_map>
#include <utility>
@@ -248,7 +249,23 @@ Value* get_operand(llvm::Value *v,
unsigned size = DL->getTypeAllocSize(gv->getValueType());
unsigned align = gv->getPointerAlignment(*DL).valueOrOne().value();
- string name = '@' + gv->getName().str();
+ string name;
+ if (!gv->hasName()) {
+ unsigned id = 0;
+ auto M = gv->getParent();
+ auto i = M->global_begin(), e = M->global_end();
+ for (; i != e; ++i) {
+ if (i->hasName())
+ continue;
+ if (&(*i) == gv)
+ break;
+ ++id;
+ }
+ assert(i != e);
+ name = '@' + to_string(id);
+ } else {
+ name = '@' + gv->getName().str();
+ }
auto val = make_unique<GlobalVariable>(*ty, move(name), size, align,
gv->isConstant());
gvar = val.get();

ADD
tests/alive-tv/memory/glb-anonymous-2.src.ll
+@0 = constant i32 1
+@x = constant i32 2
+@1 = constant i32 3
+
+define i32 @f() {
+ %a = load i32, i32* @0
+ %b = load i32, i32* @x
+ %c = load i32, i32* @1
+
+ %p = mul i32 100, %a
+ %q = mul i32 10, %b
+
+ %res0 = add i32 %p, %q
+ %res = add i32 %res0, %c
+ ret i32 %res
+}

ADD
tests/alive-tv/memory/glb-anonymous-2.tgt.ll
+@0 = constant i32 1
+@x = constant i32 2
+@1 = constant i32 3
+
+define i32 @f() {
+ ; reordered
+ %b = load i32, i32* @x
+ %c = load i32, i32* @1
+ %a = load i32, i32* @0
+
+ ret i32 123
+}

ADD
tests/alive-tv/memory/glb-anonymous.src.ll
+@0 = global i8 0
+@1 = global i32 0
+
+define void @f() {
+ %unused = load i8, i8* @0
+ store i32 1, i32* @1
+ ret void
+}

ADD
tests/alive-tv/memory/glb-anonymous.tgt.ll
+@0 = global i8 0
+@1 = global i32 0
+
+define void @f() {
+ store i32 1, i32* @1
+ ret void
+}

Add support for anonymous global variables (#216)