Det kan vara rimligt att uppskatta att storleken p˚a den nya funktionaliteten till storleken av den nuvarande PBQPBuilderWithCoalescing klassen med alla metoder. Om man r¨aknar ihop allt samman blir det totalt ca 130 rader kod. Det ¨ar inte s˚a mycket, men det kan dock bli mer om man vill im-plementera register pairing f¨or flera fall eller om man vill g¨ora en generell l¨osning med st¨od i tablegen. Det ¨ar inte heller helt l¨att att skriva den h¨ar koden om man inte har full koll p˚a de olika objekt och datastrukturer som anv¨ands i kodgenereringslagret. En gissning p˚a hur l˚ang tid det skulle kunna ta att f˚a till en f¨ardig testad l¨osning ligger mellan 2 veckor till 3 m˚anader, beroende p˚a hur bra koll man har p˚a LLVM.
I en egen l¨osning vill man f¨ormodligen ocks˚a f¨ora in nya f¨or¨andringar som g¨ors i RegAllocPBQP.cpp ¨over tiden . Man m˚aste d˚a ¨aven se till att h˚alla sig kompatibel mot de f¨or¨andringar som g¨ors i resten av LLVM. LLVM k¨or SVN f¨or versionshantering, men det hj¨alper inte mycket eftersom att man ¨
and˚a kommer att f˚a konflikter mellan de f¨or¨andringar man sj¨alv gjort och LLVM teamets f¨or¨andringar n¨ar man f¨ors¨oker uppdatera k¨allkoden. Som jag n¨amnt tidigare kan f¨or¨andringarna vara ganska omfattande mellan olika versioner.
3.A Pseudokod
Nedan f¨oljer pseudokod f¨or n˚agra av de viktigaste metoderna i RegAllocPBQP.cpp. Detta kan vara bra, kanske f¨or att f˚a en hj¨alp att f¨orst˚a koden i LLVM. Pseudokod f¨or sj¨alva l¨osningsalgoritmen kan hittas i rapporten Register Al-location for Irregular Architectures av Scholz et al. [1].
/* This function contains the main allocation loop. */ runOnMachineFunction {
find vreg intervals in need of allocation; if there are non-empty intervalls {
while allocation not complete { if coalescing is enabled {
problem := construct the PBQP problem
using the builder with coalescing; } else {
problem := construct the PBQP problem
usingh the normal build function; }
problem := build the PBQP problem with build(); solution := solve it using the PBQP solver;
map the solution back to the problem
using mapPBQPToRegAlloc(problem, solution);
check if the allocation is complete; }
} }
/* Build the pbqp problem. */ PBQPBuilder::build () {
pbqpProblem := new pbqp problem with a supposedly empty or initial PBQP graph;
graph := the graph from pbqpProblem;
for each live intervall {
mark all physical register as used; }
for each virtual register {
compute an initial allowed set;
remove all physical register which overlap; remove all aliases;
vector := compute a cost vector from the allowed set; create a node with this cost vector;
add the node to the graph; add spill costs for the node; }
for each virtual register as v1 { live1 : = get live intervall for v1; for each virtual register as v2 {
live2 : = get live intervall for v2; if live1 and live2 overlap {
node1 := get the node in
the graph representing v1; node2 := get the node in
the graph representing v2;
matrix := cost matrix for node1 and node2;
add an edge in the graph between
node1 and node2 and assign the interence matrix to the edge;
} } }
return pbqpProblem; }
/* Build the pbqp problem and do coalescing. */ PBQPBuilderWithCoalescing::build () {
/* We first construct the problem using the normal build function.. */
pbqpProblem := PBQPBuilder::build();
/* ..then we do coalescing. */
for each machine basic block as block { for each machine isntruction as instr {
if the virtual registers in instr are not coalescable {
skipp this instruction and continue; }
if the source and dest vreg are the same { /* Already coalesced */
skipp this instruction and continue; }
compute coalesce benefit;
if this coalesce pair is physical { if the live interval of the dest vreg
skipp and continue; }
count the number of options availiable
based on the allowed set of the source vreg; add phycial coalese;
update cost vector; } else {
node1 := node for dest vreg; node2 := node for source vreg;
edge := find edge in graph for node1 and node2; if not found {
matrix := construct cost matrix from the allowed sets of dest vreg and source vreg;
edge := add an edge in the graph between node1 and node2 with the cost matrix; } else {
if the first node conected by the edge is equal to node2 { swap node1 with node2;
swap the allowed sets of the nodes; }
}
Add a virtual register coalesce, with edge costs from the edge, the allowed sets for node1,
node2 and the coalesce bennefit; }
} } }
/* Map the solution back to the problem. */ RegAllocPBQP::mapPBQPToRegAlloc() {
clear the previous allocation;
/* We’re going to do a new one right here. */
for each node in the graph { if a physical register has been
choosen for this node {
assign a physical register to this node; } else if spilling has been
choosen for this node { remove the old interval;
add the new intervals to the PBQP graph; }
}
if new spills where added {
returnValue := we need another
round with the solver; } else {
returnValue := allocation is complete; }
return returnValue; }
4. Resultat
4.1 Slutsatser
Jag har i den h¨ar ¨ar rapporten visat hur man i teorin kan modellera par och alias i en interferensgraf f¨or anv¨andning med PBQP. Jag har ocks˚a g˚att igenom vad som i dagsl¨aget finns implementerat i LLVM och gett f¨orslag p˚a hur man skulle kunna g˚a till v¨aga f¨or att l¨agga till st¨od f¨or registerpar. Det som slutligen kan konstateras ¨ar:
• PBQP ger m¨ojlighet att modellera m˚anga olika typer av begr¨ansningar, bland annat par och alias.
• Det praktiska problemet ligger i att konstruera PBQP grafen och s¨atta in r¨att kostnadsmatris p˚a r¨att st¨alle. N¨ar problemet v¨al ¨ar beskrivet kan det l¨osas enligt l¨osningsalgoritmen f¨or PBQP, vilken beskrivs i sin helhet i [1].
• St¨od f¨or registerpar saknas i dagsl¨aget i PBQP implementationen i LLVM.
• En ev. implementation kan g¨oras antingen i egen regi eller som ett samarbete med LLVM teamet.
• F¨or att kunna g¨ora en generell l¨oning som st¨odjer alla typer av be-gr¨ansningar b¨or st¨od f¨or PBQP implementeras i LLVMs targetspeci-fikation.
• Storleken p˚a en minimal egen l¨oning kan uppskattas till ca 130 rader, men kan komma att bli mycket st¨orre och avancerad f¨or att t¨acka alla olika typer av parrelationer.
• Vid en eventuell implementation av st¨od f¨or registerpar m˚aste den nuvarande coalescing koden med st¨orsta sannolikhet anpassas.