ZAM bug fix for incorrect management of global variables

This commit is contained in:
Vern Paxson 2023-06-14 17:44:48 -07:00
parent 5722596970
commit 40054e5f77
3 changed files with 29 additions and 32 deletions

View file

@ -333,7 +333,10 @@ private:
// Returns how many values were added.
int InternalAddVal(ZInstAux* zi, int i, Expr* e);
const ZAMStmt AddInst(const ZInstI& inst);
// Adds the given instruction to the ZAM program. The second
// argument, if true, suppresses generation of any pending
// global/capture store for this instruction.
const ZAMStmt AddInst(const ZInstI& inst, bool suppress_non_local = false);
// Returns the statement just before the given one.
ZAMStmt PrevStmt(const ZAMStmt s);

View file

@ -128,7 +128,7 @@ int ZAMCompiler::InternalAddVal(ZInstAux* zi, int i, Expr* e)
return 1;
}
const ZAMStmt ZAMCompiler::AddInst(const ZInstI& inst)
const ZAMStmt ZAMCompiler::AddInst(const ZInstI& inst, bool suppress_non_local)
{
ZInstI* i;
@ -146,17 +146,22 @@ const ZAMStmt ZAMCompiler::AddInst(const ZInstI& inst)
top_main_inst = insts1.size() - 1;
if ( pending_global_store < 0 )
if ( suppress_non_local )
return ZAMStmt(top_main_inst);
auto global_slot = pending_global_store;
pending_global_store = -1;
if ( pending_global_store >= 0 )
{
auto gs = pending_global_store;
pending_global_store = -1;
auto store_inst = ZInstI(OP_STORE_GLOBAL_V, global_slot);
store_inst.op_type = OP_V_I1;
store_inst.t = globalsI[global_slot].id->GetType();
auto store_inst = ZInstI(OP_STORE_GLOBAL_V, gs);
store_inst.op_type = OP_V_I1;
store_inst.t = globalsI[gs].id->GetType();
return AddInst(store_inst);
return AddInst(store_inst);
}
return ZAMStmt(top_main_inst);
}
const Stmt* ZAMCompiler::LastStmt(const Stmt* s) const

View file

@ -66,7 +66,7 @@ const ZAMStmt ZAMCompiler::LoadGlobal(const ID* id)
z.aux = new ZInstAux(0);
z.aux->id_val = id;
return AddInst(z);
return AddInst(z, true);
}
int ZAMCompiler::AddToFrame(const ID* id)
@ -81,38 +81,27 @@ int ZAMCompiler::FrameSlot(const ID* id)
auto slot = RawSlot(id);
if ( id->IsGlobal() )
(void)LoadGlobal(frame_denizens[slot]);
(void)LoadGlobal(id);
return slot;
}
int ZAMCompiler::Frame1Slot(const ID* id, ZAMOp1Flavor fl)
{
auto slot = RawSlot(id);
if ( fl == OP1_READ )
return FrameSlot(id);
switch ( fl )
{
case OP1_READ:
if ( id->IsGlobal() )
(void)LoadGlobal(frame_denizens[slot]);
break;
if ( fl == OP1_INTERNAL )
return RawSlot(id);
case OP1_WRITE:
if ( id->IsGlobal() )
pending_global_store = global_id_to_info[id];
break;
ASSERT(fl == OP1_WRITE || fl == OP1_READ_WRITE);
case OP1_READ_WRITE:
if ( id->IsGlobal() )
{
(void)LoadGlobal(frame_denizens[slot]);
pending_global_store = global_id_to_info[id];
}
break;
// Important: get the slot *before* tracking non-locals, so we don't
// prematurely generate a Store for the read/write case.
auto slot = fl == OP1_READ_WRITE ? FrameSlot(id) : RawSlot(id);
case OP1_INTERNAL:
break;
}
if ( id->IsGlobal() )
pending_global_store = global_id_to_info[id];
return slot;
}