Skip to content
Snippets Groups Projects
Commit c94c0202 authored by whh8b's avatar whh8b
Browse files

Refactor UpdateTargets and AddNewDollop

Move functionality to determine if a dollop for
an instruction already exists and whether to split
the containing dollop into AddNewDollop and use
that to implement UpdateTargets.
parent 9850eb8c
No related branches found
No related tags found
No related merge requests found
......@@ -9,9 +9,40 @@ using namespace libIRDB;
namespace zipr {
Dollop_t *ZiprDollopManager_t::AddNewDollop(Instruction_t *start) {
Dollop_t *new_dollop = Dollop_t::CreateNewDollop(start);
AddDollop(new_dollop);
return new_dollop;
Dollop_t *new_dollop = NULL;
Dollop_t *existing_dollop = GetContainingDollop(start);
/*
* This is the target dollop *only*
* if the target instruction is the first instruction.
*/
if (existing_dollop)
{
/*
* There is a target dollop. But, do we need to split it?
*/
if (existing_dollop->GetDollopEntryCount() &&
existing_dollop->front()->Instruction() == start) {
/*
* Just return the existing dollop.
*/
return existing_dollop;
}
else {
/*
* Split at this dollop to make a new one!
*/
AddDollop(new_dollop = existing_dollop->Split(start));
return new_dollop;
}
}
else {
/*
* There is no target dollop. Let's create one!
*/
new_dollop = Dollop_t::CreateNewDollop(start);
AddDollop(new_dollop);
return new_dollop;
}
}
void ZiprDollopManager_t::PrintDollopPatches(const ostream &out) {
......@@ -57,45 +88,13 @@ namespace zipr {
DollopEntry_t *entry = *it;
if (entry->Instruction() &&
entry->Instruction()->GetTarget()) {
/*
* Update target.
*/
Dollop_t *target_dollop = GetContainingDollop(entry
->Instruction()
->GetTarget());
/*
* This is the target dollop *only*
* if the target instruction is the first instruction.
*/
if (target_dollop)
{
/*
* There is a target dollop. But, do we need to split it?
*/
if (target_dollop->GetDollopEntryCount() &&
target_dollop->front()->Instruction() == entry->Instruction()->GetTarget()) {
/*
* Just update the target.
*/
entry->TargetDollop(target_dollop);
}
else {
/*
* Split at this dollop to make a new one!
*/
AddDollop(target_dollop->Split(entry->Instruction()->GetTarget()));
}
}
else {
/*
* There is no target dollop. Let's create one!
*/
AddNewDollop(entry->Instruction()->GetTarget());
}
entry->TargetDollop(AddNewDollop(entry->Instruction()->GetTarget()));
}
}
return;
}
std::ostream &operator<<(std::ostream &out, const ZiprDollopManager_t &dollop_man) {
std::list<Dollop_t *>::const_iterator it, it_end;
......
......@@ -119,6 +119,46 @@ bool TestDollopPatchDollopManager(void) {
return true;
}
bool TestAddNewDollopSplitsExistingDollop(void) {
bool success = true;
ZiprDollopManager_t dollop_man;
Dollop_t *a, *b;
libIRDB::Instruction_t *insn_a = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_b = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_c = new libIRDB::Instruction_t();
libIRDB::Instruction_t *insn_d = new libIRDB::Instruction_t();
/*
* a targets c
* c targets d (which will ultimately create a new dollop)
* a->b->c->d
*
* A: a, b, c, d
*/
insn_a->SetFallthrough(insn_b);
insn_b->SetFallthrough(insn_c);
insn_c->SetFallthrough(insn_d);
a = Dollop_t::CreateNewDollop(insn_a);
dollop_man.AddDollop(a);
success = (a->GetDollopEntryCount() == 4) && dollop_man.Size() == 1;
cout << "Before AddNewDollop()." << endl;
cout << dollop_man << endl;
b = dollop_man.AddNewDollop(insn_c);
cout << "After AddNewDollop()." << endl;
cout << dollop_man << endl;
return success &&
a->GetDollopEntryCount() == 2 &&
b->GetDollopEntryCount() == 2 &&
dollop_man.Size() == 2;
}
bool TestUpdateTargetsDollopManager(void) {
bool success = true;
ZiprDollopManager_t dollop_man;
......@@ -295,5 +335,6 @@ int main(int argc, char *argv[])
INVOKE(TestDollopPatchDollopManager);
INVOKE(TestDollopPatchMapDollopManager);
INVOKE(TestUpdateTargetsDollopManager);
INVOKE(TestAddNewDollopSplitsExistingDollop);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment