Raise unsupported error if non-const glb is introduced in tgt
MODIFY
ir/globals.cpp
ir/globals.cpp
@@ -15,7 +15,6 @@ unsigned num_locals_tgt;
unsigned num_consts_src;
unsigned num_globals_src;
unsigned num_ptrinputs;
-unsigned num_extra_nonconst_tgt;
unsigned num_nonlocals;
unsigned num_nonlocals_src;
unsigned bits_poison_per_byte;

MODIFY
ir/memory.cpp
ir/memory.cpp
@@ -27,10 +27,8 @@ using namespace util;
// num_globals_src + num_ptrinputs + 1 ~ num_nonlocals_src - 2:
// 5. a block reserved for encoding the memory touched by calls:
// num_nonlocals_src - 1
- // 6. global vars in target only:
- // num_nonlocals_src ~ num_nonlocals_src + num_extra_nonconst_tgt - 1
- // (non-constant globals in target only)
- // num_nonlocals_src + num_extra_nonconst_tgt ~ num_nonlocals - 1
+ // 6. constant global vars in target only:
+ // num_nonlocals_src ~ num_nonlocals - 1
// (constant globals in target only)
//--- Functions for non-local block analysis based on bid ---//
@@ -48,8 +46,7 @@ static bool is_constglb(unsigned bid) {
// src constglb
assert(is_globalvar(bid, false));
return true;
- } else if (num_nonlocals_src + num_extra_nonconst_tgt <= bid &&
- bid < num_nonlocals) {
+ } else if (num_nonlocals_src <= bid && bid < num_nonlocals) {
// tgt constglb
assert(!is_globalvar(bid, false) &&
is_globalvar(bid, true));
@@ -1700,9 +1697,7 @@ StateValue Memory::load(const Pointer &ptr, const Type &type, set<expr> &undef,
for (unsigned i = num_nonlocals_src; i < numNonlocals(); ++i) {
I->second.setMayAlias(false, i);
}
- state->addPre(!val.non_poison || islocal || bid.ule(*max_bid) ||
- (num_extra_nonconst_tgt ? bid.uge(num_nonlocals_src)
- : false));
+ state->addPre(!val.non_poison || islocal || bid.ule(*max_bid));
}
}
}

MODIFY
ir/pointer.cpp
ir/pointer.cpp
@@ -170,8 +170,7 @@ expr Pointer::isConstGlobal() const {
auto generic = bid.uge(has_null_block) &&
expr(num_consts_src > 0) &&
bid.ule(num_consts_src + has_null_block - 1);
- auto tgt = bid.uge(num_nonlocals_src + num_extra_nonconst_tgt) &&
- bid.ule(num_nonlocals - 1);
+ auto tgt = bid.uge(num_nonlocals_src) && bid.ule(num_nonlocals - 1);
return !isLocal() && (generic || tgt);
}
@@ -526,8 +525,8 @@ expr Pointer::isWritable() const {
expr non_local
= num_consts_src == 1 ? bid != has_null_block :
(num_consts_src ? bid.ugt(has_null_block + num_consts_src - 1) : true);
- if (m.numNonlocals() > num_nonlocals_src + num_extra_nonconst_tgt)
- non_local &= bid.ult(num_nonlocals_src + num_extra_nonconst_tgt);
+ if (m.numNonlocals() > num_nonlocals_src)
+ non_local &= bid.ult(num_nonlocals_src);
return isLocal() || non_local;
}

MODIFY
tests/alive-tv/attrs/noread.srctgt.ll
tests/alive-tv/attrs/noread.srctgt.ll
; ERROR: Source is more defined
-@glb = external global i8, align 1
-
-define void @src(i8 %var) writeonly {
+define void @src(i8 %var, i8* %p) writeonly {
ret void
}
-define void @tgt(i8 %var) writeonly {
- %x = load i8, i8* @glb
+define void @tgt(i8 %var, i8* %p) writeonly {
+ %x = load i8, i8* %p
ret void
}

ADD
tests/alive-tv/globals/consttgt.src.ll
+@var_10 = global i8 0, align 1
+
+define void @test() {
+entry:
+ store i8 1, i8* @var_10, align 1
+ ret void
+}

ADD
tests/alive-tv/globals/consttgt.tgt.ll
+@var_10 = global i8 0, align 1
+@var_11 = constant i8 0, align 1
+
+define void @test() {
+entry:
+ store i8 1, i8* @var_10, align 1
+ %q = load i8, i8* @var_11, align 1
+ ret void
+}
+

ADD
tests/alive-tv/globals/nonconsttgt.src.ll
+@var_10 = global i8 0, align 1
+
+define void @test() {
+entry:
+ store i8 1, i8* @var_10, align 1
+ ret void
+}
+
+; CHECK: Unsupported interprocedural transformation: non-constant global variable @var_11 is introduced in target

ADD
tests/alive-tv/globals/nonconsttgt.tgt.ll
+@var_10 = global i8 0, align 1
+@var_11 = global i8 0, align 1
+
+define void @test() {
+entry:
+ store i8 1, i8* @var_10, align 1
+ store i8 2, i8* @var_11, align 1
+ ret void
+}
+

MODIFY
tools/transform.cpp
tools/transform.cpp
@@ -760,7 +760,6 @@ static void calculateAndInitConstants(Transform &t) {
heap_block_alignment = 8;
num_consts_src = 0;
- num_extra_nonconst_tgt = 0;
for (auto GV : globals_src) {
if (GV->isConst())
@@ -772,8 +771,6 @@ static void calculateAndInitConstants(Transform &t) {
[GVT](auto *GV) -> bool { return GVT->getName() == GV->getName(); });
if (I == globals_src.end()) {
++num_globals;
- if (!GVT->isConst())
- ++num_extra_nonconst_tgt;
}
}
@@ -1120,6 +1117,19 @@ Errors TransformVerify::verify() const {
return { ss.str(), false };
}
}
+ for (auto GVT : globals_tgt) {
+ auto I = find_if(globals_src.begin(), globals_src.end(),
+ [GVT](auto *GV) -> bool { return GVT->getName() == GV->getName(); });
+ if (I != globals_src.end())
+ continue;
+
+ if (!GVT->isConst()) {
+ string s = "Unsupported interprocedural transformation: non-constant "
+ "global variable " + GVT->getName() + " is introduced in"
+ " target";
+ return { move(s), false };
+ }
+ }
Errors errs;
try {

Raise unsupported error if non-const glb is introduced in tgt (#759)