123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
- package targets.mips;
- import API.Api;
- import API.MiddlewareInterface;
- import common.AllocatorInterface;
- import common.Code;
- import common.Instruction;
- import java.util.LinkedHashMap;
- import java.util.LinkedList;
- import middlewares.BasicBlockMiddleware;
- import middlewares.BlockBaseGroup;
- import middlewares.BlockBaseOcorrences;
- import middlewares.Interval;
- /**
- *
- * @author EUGENIO CARVALHO
- */
- public class MipsRegisterAllocMiddleware implements AllocatorInterface, MiddlewareInterface {
- protected int instructionPosition;
- protected Code tac;
- protected Registers registers;
- protected BlockBaseGroup group;
- protected LinkedList<String> free = new LinkedList<>();
- protected BasicBlockMiddleware blockProcessor;
- protected String[] withoutRegister = "jump,call,return".split(",");
- public MipsRegisterAllocMiddleware() {
- }
- @Override
- public void Exec(Code c, LinkedHashMap<String, MiddlewareInterface> cp) throws Exception {
- BlockBaseOcorrences bb;
- System.out.println("AllocatorMipsProcessor:");
- Code IR = c.Parent;
- String blockname = c.Block().getName();
- IR.Use(blockname);
- registers = new Registers();
- blockProcessor = (BasicBlockMiddleware) cp.get("ir.basic.blocks");
- instructionPosition = 0;
- group = blockProcessor.getBasicBlockGroup(IR.Block().getName());
- group.Init();
- for (Instruction inst : IR.Block().Instructions()) {
- // ignora se a instrução for do tipo controle
- if (inst.in("type", IR.ControlInstructions)) {
- continue;
- }
- // Se a instrução possui enderecamento de registradores
- if (!inst.in("type", withoutRegister)) {
- // Se a instruncao pertence ao proximo bloco basico atualiza o grupo
- bb = group.getBasicBlocks(1);
- // System.out.println("###ASSIGN:(" + instructionPosition + ")(" + group.getBasicBlocks(1).getLeader() + ")");
- if (bb != null && instructionPosition >= bb.getLeader()) {
- group.NextBlock();
- // System.out.println(">>>>> Mudei para bloco basico:" + group.Current().getName());
- }
- // Libera registradores alocados temporariamente
- while (!free.isEmpty()) {
- registers.Free(free.pop());
- }
- // Atribui os registradores a instrucao
- Assign(inst);
- }
- // Incrimenta o ponteiro para a proxima instrucao
- instructionPosition++;
- }
- // System.out.println(group);
- }
- @Override
- public void Alloc(Code code) {
- this.tac = code;
- }
- protected void Assign(Instruction inst) throws Exception {
- // System.out.println("Assign:" + inst.Get("type") + ":" + inst.Get("local.position"));
- String reg;
- String[] opDeslocamento = "<<,>>".split(",");
- for (String param : new String[]{"p1", "p2", "dst.indice", "p1.indice"}) {
- if (!inst.Has(param) || ((inst.in("op", opDeslocamento) && param.equals("p2")))) {
- continue;
- }
- // System.out.println("PARAM:[" + param + "value" + "]" + x.eq(param + "value", "true"));
- // if (!x.in("op", opDeslocamento)) {
- // } else
- if (inst.eq(param + "value", "true") || inst.isNumber(param)) {
- reg = registers.Lock("t");
- free.push(reg);
- Load(inst, param);
- } else {
- // System.out.println("GX:" + param + "->" + x);
- reg = GetRegister(inst, param);
- }
- inst.Set("reg." + param, reg);
- // System.out.println("Assign:[" + param + "]" + inst);
- }
- if (inst.Has("dst")) {
- inst.Set("reg.dst", GetRegister(inst, "dst"));
- }
- }
- protected void Load(Instruction x, String param) {
- x.Set("reg." + param + ".load", "true");
- }
- protected String GetRegister(Instruction x, String address) throws Exception {
- BlockBaseOcorrences bb = group.Current();
- String reg, addr = bb.ToAliase(x, address);
- int position = x.GetInt("block.position"), leader = bb.getLeader();
- // Corrige a posicao para iniciar de 0 para cada bloco basico referente ao lider de cada bloco.
- position = (leader == 0) ? position : position - leader;
- boolean dst = address.equals("dst");
- // System.out.println("GetRegister: (" + address + "):(" + addr + ") : ["
- // + instructionPosition
- // + " : "
- // + position
- // + " : "
- // + leader + "]");
- // System.out.println(x);
- Interval interval = bb.Get(addr, position);
- // System.out.println(bb);
- // System.out.println(interval);
- // System.out.println("}");
- // Define um registrador se não possuir um definido no intervalo
- if (!interval.RegisterDefined()) {
- // System.out.println("Não tinha definido: Carregar da memoria(" + (!dst) + ")");
- // Verifica a existencia de um registrador disponivel
- reg = AvaliableRegister(addr);
- // System.out.println("[" + dst + "]GerRegister não definido: (" + address + ")/add: " + addr);
- if (!dst) {
- // Parametro define que o valor deve ser carregado em registrador;
- Load(x, address);
- }
- // Libera um registrador ocupado
- if (reg == null) {
- // System.out.println("spill" + bb + " P:" + position + " b:" + bb.Spill(position));
- reg = bb.Spill(position).getRegister();
- }
- // Vincula o registrador com o intervalo
- interval.setRegister(reg);
- } else {
- reg = interval.getRegister();
- // Se escreve no registrador e não é o ultimo intervalo marca para
- // ser salvo marca para ser salvo.
- // if (dst && !group.Last(addr).equals(interval)) {
- // Libera o registrador
- // System.out.println("Tinha definido::" + reg + ":Liberadp{" + addr + "}:" + (interval.End == position));
- }
- if (dst) {
- interval.Perisist(true);
- }
- // Se for
- // -> A ultima ocorrencia do intervalo e
- // -> O registrador é saved e
- // -> Ocorreu escrita no registrador
- // -> Ponteiros e variaveis globais devem persistidas apos cada operacao de escrita
- // marca para gravar em memoria
- if (interval.End == position) {
- registers.Free(reg);
- // System.out.println("reg(" + reg + ")persist(" + interval.Perisist() + ")");
- if (reg.substring(0, 1).equals("s")
- && interval.Perisist()) {
- x.Set("reg." + address + ".store", "true");
- }
- }
- // System.out.println("}" + reg + "::" + position);
- return reg;
- }
- protected String AvaliableRegister(String alias) throws Exception {
- String reg = "";
- switch (Api.clearID(alias).substring(1, 2)) {
- case "V":
- case "G":
- reg = "s";
- break;
- case "T":
- case "C":
- reg = "t";
- break;
- default:
- throw new Exception(String.format("Not avaliable register to alias '%s'", alias));
- }
- return registers.Lock(reg);
- }
- protected String PopReturnRegister() {
- return null;
- }
- @Override
- public void Get(String id, int position) {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
- }
- //leadersList:[0, 3, 7, 8]
- // : <bitCount>:
- //13: 0: pop_param _V4 T< pop_param >
- //14: 1: _V5 := 0 T< copy >
- //15: 2: if _V4 <= 0 goto <bitCount+_i4> T< branch >
- // : <bitCount+_i6>:
- //16: 3: _V5 := _V5 + 1 T< assign >
- //17: 4: _T6 := _V4 - 1 T< assign >
- //18: 5: _V4 := _V4 & _T6 T< assign >
- //19: 6: if _V4 == 0 goto <bitCount+_i7> T< branch >
- //20: 7: goto <bitCount+_i6> T< jump >
- // : <bitCount+_i7>:
- // : <bitCount+_i4>:
- //21: 8: push_return _V5 T< push_return >
- //22: 9: return 1 T< return >
- // : <bitCount-end>:
|