[LLVMdev] Folding instructions

Fernando Magno Quintao Pereira fernando at CS.UCLA.EDU
Mon Aug 14 11:40:17 PDT 2006


> Hi Fernando,
>
> It's hard to say exactly what's happening because I don't know your
> code (though, from the stack trace, it seems like there's some sort
> of memory debacle), but looking at the comment in the
> LiveVariableAnalysis.cpp file where it's folding memory operands, it
> might explain somethings better:
>
>              // Folding the load/store can completely change the
> instruction in
>              // unpredictable ways, rescan it from the beginning.
>
> It's after this that it re-analyzes the operands of the machine
> instruction. Are you doing this?
>
> -bw


Thanks, Bill.

    I am iterating on the instruction, as linear scan does, but I am still
getting the memory error. If I print data, the error does not happen. But
I realized something important: I am not mapping virtuals to physicals
strait on VirtRegMap during the scan. I use my own data structures to
record the register assignment, and write on VirtRegMap after I am done,
on a single step. When I remove the command this->vrm->virtFolded(v_reg,
mi, u, fmi) from my code, the error does not happen. So, I think I am not
using VirtRegMap properly. It seems to me that I don't have to call this
method during the scan, because instruction operands still contain
virtuals, not physical registers, as it would be expected. Is this right?
If someone has time to look into it, I am sending the piece of code where
I reload spilled code. If I am doing something evidently wrong, I would
appreciate if someone tells me. With the comment on vrm->virtFolded, I am
passing all the tests that I have.

All the best,

Fernando

MachineInstr * RegAllocChordal_Fer::allocate_spilled_uses
                              (MachineInstr * mi, KillingSites_Fer & ks) {
  if(mi->getOpcode() != TargetInstrInfo::PHI) {
    /// This set helps to avoid allocating the same use twice. Even if a
    /// virtual is used twice or more in an instruction, it only needs one
    /// physical register.
    std::set<unsigned> seen_regs;
    for(unsigned u = 0; u < mi->getNumOperands(); u++) {
      const MachineOperand & mo = mi->getOperand(u);
      if(mo.isUse() && mo.isRegister() && mo.getReg()) {
        if(MRegisterInfo::isVirtualRegister(mo.getReg())) {
          unsigned v_reg = mo.getReg();
          if(this->vrm->hasStackSlot(v_reg)) {
            int slot = this->vrm->getStackSlot(v_reg);
            // First, try to fold the memory reference into the
            // instruction. If we can do this, we don't need to
            // insert spill code.
            const TargetMachine & target_machine =
                               this->machine_function->getTarget();
            const MRegisterInfo *ri =
                                  target_machine.getRegisterInfo();
            MachineInstr * fmi =
                                ri->foldMemoryOperand(mi, u, slot);
            if(fmi) {
              numFolded++;
              MachineBasicBlock * mbb = mi->getParent();
------>       //this->vrm->virtFolded(v_reg, mi, u, fmi);
              ks.fold_inst(mi, fmi);
              // TODO: see if it is not necessary to iterate
              // again on the instruction.
              mi = mbb->insert(mbb->erase(mi), fmi);
              u = 0;
              seen_regs.clear();
              continue;
            }
            // It was not possible to fold the spill into the
            // instruction: a register must be fond.
            if(seen_regs.find(v_reg) != seen_regs.end()) {
              continue;
            } else {
              seen_regs.insert(v_reg);
            }
            unsigned p_reg = reg_mapping->get_free_register(v_reg);
            if(p_reg != RegMapping_Fer::NO_REG) {
              this->reg_mapping->allocate_color(v_reg, p_reg);
            } else {
              // unused register may conflict with this virtual, because
              // they may be pre-colored, for instance.
              unsigned p_reg = reg_mapping->get_unused_reg(v_reg);
              if(p_reg != RegMapping_Fer::NO_REG) {
                reg_mapping->allocate_color(v_reg, p_reg);
              } else {
                const MachineOperand * spill_op =
                                    choose_reg_to_spill(v_reg);
                unsigned spill_v = spill_op->getReg();
                unsigned p_reg =
                   reg_mapping->get_physical_location(spill_v);
                spill(* spill_op, ks, * mi->getParent());
                reg_mapping->allocate_color(v_reg, p_reg);
              }
            }
          }
        }
      }
    }
  }
  return mi;
}



More information about the llvm-dev mailing list