• No results found

Utveckling och underh˚ all

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.

Related documents