> 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? > > -bwThanks, 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; }
On Mon, 14 Aug 2006, Fernando Magno Quintao Pereira wrote:> 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.I haven't had a chance to look at the code you have below, but I would guess that you are leaving a dangling pointer in some map somewhere. "foldMemoryOperand", if successful, leaves the original instruction in the program. When you delete this instruction (which is require to avoid miscompiling the program) you must inform virtregmap that you've done this, by calling 'virtFolded'. This is important, because it allows the virtregmap to remove the (about to be deleted) instruction from *its* internal maps. If you are still getting stuck, I'd try running valgrind on llc with the bad code, it is quite good at flushing out these sorts of problems. -Chris> > 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; > } > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-Chris -- http://nondot.org/sabre/ http://llvm.org/
> If you are still getting stuck, I'd try running valgrind on llc with the > bad code, it is quite good at flushing out these sorts of problems.Thank you, Chris. I just tried to install valgrind, but it seems to me it does not work on Mac OS. Do you know if it is true? Is there any valgrind like application that I can use on Mac OS? regards, Fernando