Skip to content
Snippets Groups Projects
Commit 5dae3c05 authored by Jason Hiser's avatar Jason Hiser :tractor:
Browse files

dealing with making sure personality routines get placed if a dollop uses them

parent b55ab9f1
No related branches found
No related tags found
No related merge requests found
Pipeline #1004 passed
......@@ -1129,6 +1129,34 @@ void ZiprImpl_t::PlaceDollops()
for ( /* empty */; dit != dit_end; dit++)
{
DollopEntry_t *dollop_entry = *dit;
/*
* first, check if we need to add any reference dollops to the placement queue
*/
const auto handle_reloc=[&](const Relocation_t* reloc)
{
auto wrt_insn=dynamic_cast<Instruction_t*>(reloc->GetWRT());
if(wrt_insn)
{
auto containing=m_dollop_mgr.GetContainingDollop(wrt_insn);
assert(containing!=nullptr);
if(!containing->IsPlaced())
{
placement_queue.insert(pair<Dollop_t*, RangeAddress_t>( containing, cur_addr));
cout<<"Adding to placement queue for reloc of type="<<reloc->GetType()<<endl;
}
}
};
// make sure each instruction referenced via a relocation is placed in a dollop
auto insn=dollop_entry->Instruction();
for(auto &reloc : insn->GetRelocations())
handle_reloc(reloc);
auto ehpgm=insn->GetEhProgram();
if(ehpgm)
for(auto &reloc : ehpgm->GetRelocations())
handle_reloc(reloc);
/*
* There are several ways that a dollop could end:
* 1. There is no more fallthrough (handled above with
......@@ -1320,11 +1348,7 @@ void ZiprImpl_t::PlaceDollops()
* even if we do coaelesce something its fallthrough could
* be preplaced ...
*/
if (!am_coalescing &&
to_place->FallthroughDollop() &&
fallthrough_has_preplacement &&
fallthrough_dollop_place == cur_addr
)
if (!am_coalescing && to_place->FallthroughDollop() && fallthrough_has_preplacement && fallthrough_dollop_place == cur_addr)
{
if (m_verbose)
cout << "Dollop had a fallthrough dollop and "
......@@ -1767,9 +1791,6 @@ RangeAddress_t ZiprImpl_t::_PlopDollopEntry(DollopEntry_t *entry, RangeAddress_t
return updated_addr;
}
#define IS_RELATIVE(A) \
((A.ArgType & MEMORY_TYPE) && (A.ArgType & RELATIVE_))
RangeAddress_t ZiprImpl_t::PlopDollopEntry(
DollopEntry_t *entry,
RangeAddress_t override_place,
......
......@@ -160,20 +160,11 @@ namespace zipr {
}
Dollop_t *ZiprDollopManager_t::GetContainingDollop(libIRDB::Instruction_t *insn) {
#if 0
try {
return m_insn_to_dollop.at(insn);
} catch (const std::out_of_range &oor) {
return NULL;
}
return NULL;
#else
InsnToDollopMap_t::iterator it=m_insn_to_dollop.find(insn);
if(it!=m_insn_to_dollop.end())
return it->second;
return NULL;
#endif
}
void ZiprDollopManager_t::AddDollops(Dollop_t *dollop_head) {
......@@ -212,70 +203,70 @@ namespace zipr {
* Push the actual dollop onto the list of dollops
* if it's not already there.
*/
#if 0
if (m_dollops.end()==std::find(m_dollops.begin(), m_dollops.end(), dollop))
m_dollops.push_back(dollop);
#else
m_dollops.insert(dollop);
#endif
m_dollops.insert(dollop);
m_refresh_stats = true;
}
bool ZiprDollopManager_t::UpdateTargets(Dollop_t *dollop) {
bool changed = false;
bool local_changed = false;
int local_changed_count=0;
int and_count=0;
do {
local_changed = false;
local_changed_count++;
const auto local_dollop=list<DollopEntry_t*>(dollop->begin(), dollop->end());
list<DollopEntry_t*>::const_iterator it, it_end;
for (it = local_dollop.begin(), it_end = local_dollop.end();
it != it_end;
/* nop */) {
DollopEntry_t *entry = *it;
it++;
if (entry->Instruction() &&
entry->Instruction()->GetTarget()) {
Dollop_t *new_target=AddNewDollops(entry->Instruction()->GetTarget());
and_count++;
const auto handle_reloc=[this](const Relocation_t* reloc)
{
auto wrt_insn=dynamic_cast<Instruction_t*>(reloc->GetWRT());
if(wrt_insn)
{
// we don't bother marking a change because
// we only need to do this once for relocs
// and we are certain to get here once for every dollop
AddNewDollops(wrt_insn);
cout<<"Adding new dollop for reloc of type="<<reloc->GetType()<<endl;
/*
* In the case there is a change, we have to restart.
* The dollop that we are updating could itself have
* contained the target and the call would have
* split this dollop. That makes the iterator go
* haywire.
*
* But! We could avoid the break by using a copy of the set.
*/
if (new_target != entry->TargetDollop()) {
entry->TargetDollop(new_target);
changed = local_changed = true;
//break;
}
}
};
auto changed = false;
const auto local_dollop=list<DollopEntry_t*>(dollop->begin(), dollop->end());
for (auto &entry : local_dollop )
{
auto insn=entry->Instruction();
if (insn->GetTarget())
{
auto new_target=AddNewDollops(insn->GetTarget());
/*
* In the case there is a change, we have to restart.
* The dollop that we are updating could itself have
* contained the target and the call would have
* split this dollop. That makes the iterator go
* haywire.
*
* But! We could avoid the break by using a copy of the set, which we do.
*/
if (new_target != entry->TargetDollop()) {
entry->TargetDollop(new_target);
changed = true;
}
}
// make sure each instruction referenced via a relocation is placed in a dollop
for(auto &reloc : insn->GetRelocations())
handle_reloc(reloc);
auto ehpgm=insn->GetEhProgram();
if(ehpgm)
for(auto &reloc : ehpgm->GetRelocations())
handle_reloc(reloc);
}
} while (false); // while (local_changed);
return changed;
}
void ZiprDollopManager_t::UpdateAllTargets(void) {
DollopList_t::iterator it, it_end;
bool changed = false;
int changed_count=0;
int update_count=0;
auto changed = false;
auto changed_count=0;
auto update_count=0;
do {
changed = false;
const auto local_dollops=m_dollops;
for (it = local_dollops.begin(), it_end = local_dollops.end(); it != it_end; /* nop */)
for (auto entry : local_dollops)
{
Dollop_t *entry = *it;
it++;
changed |= UpdateTargets(entry);
update_count++;
if((update_count%1000000) == 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