Robot::mCompositeBlock Robot::createBlockOfOperations(uint32_t& fromActivityId, uint32_t& fromPointId, const ActivityType& t1, const ActivityType& t2, const Interval<uint32_t>& numSeq, const Interval<uint32_t>& seqLength) const { uniform_int_distribution<uint32_t> sl(seqLength.from(), seqLength.to()); uniform_int_distribution<uint32_t> ns(numSeq.from(), numSeq.to()); mCompositeBlock blockActivities; uint32_t numberOfSequences = ns(generator); function<void(StaticActivity*)> storeActivity = [&blockActivities](StaticActivity *a) { switch (a->type()) { case IN: blockActivities.in.push_back(a); break; case INNER: blockActivities.w.push_back(a); break; default: blockActivities.out.push_back(a); } }; for (uint32_t i = 0; i < numberOfSequences; ++i) { uint32_t sequenceLength = sl(generator); StaticActivity *op1 = new StaticActivity(fromActivityId++, fromPointId, t1, mRobotModes, mParameters); blockActivities.con1.push_back(op1); storeActivity(op1); StaticActivity *op2 = nullptr; for (uint32_t l = 0; l+2 < sequenceLength; ++l) { op2 = new StaticActivity(fromActivityId++, fromPointId, INNER, mRobotModes, mParameters); DynamicActivity *op2op = new DynamicActivity(fromActivityId++, op1, op2, mParameters); blockActivities.w.push_back(op2); blockActivities.mv.push_back(op2op); op1 = op2; } if (sequenceLength == 1) { if (t1 == t2) { op2 = op1; } else { throw runtime_error("Robot::mCompositeBlock Robot::createBlockOfOperations(...): " "Sequence of unit length must have the same types of the first and last activity"); } } else { op2 = new StaticActivity(fromActivityId++, fromPointId, t2, mRobotModes, mParameters); DynamicActivity *op2op = new DynamicActivity(fromActivityId++, op1, op2, mParameters); blockActivities.mv.push_back(op2op); storeActivity(op2); } blockActivities.con2.push_back(op2); } connect(fromActivityId, blockActivities, blockActivities.con2, blockActivities.con1, false); return blockActivities; }
void LinearScan::allocate_fpu_stack() { // First compute which FPU registers are live at the start of each basic block // (To minimize the amount of work we have to do if we have to merge FPU stacks) if (ComputeExactFPURegisterUsage) { Interval* intervals_in_register, *intervals_in_memory; create_unhandled_lists(&intervals_in_register, &intervals_in_memory, is_in_fpu_register, NULL); // ignore memory intervals by overwriting intervals_in_memory // the dummy interval is needed to enforce the walker to walk until the given id: // without it, the walker stops when the unhandled-list is empty -> live information // beyond this point would be incorrect. Interval* dummy_interval = new Interval(any_reg); dummy_interval->add_range(max_jint - 2, max_jint - 1); dummy_interval->set_next(Interval::end()); intervals_in_memory = dummy_interval; IntervalWalker iw(this, intervals_in_register, intervals_in_memory); const int num_blocks = block_count(); for (int i = 0; i < num_blocks; i++) { BlockBegin* b = block_at(i); // register usage is only needed for merging stacks -> compute only // when more than one predecessor. // the block must not have any spill moves at the beginning (checked by assertions) // spill moves would use intervals that are marked as handled and so the usage bit // would been set incorrectly // NOTE: the check for number_of_preds > 1 is necessary. A block with only one // predecessor may have spill moves at the begin of the block. // If an interval ends at the current instruction id, it is not possible // to decide if the register is live or not at the block begin -> the // register information would be incorrect. if (b->number_of_preds() > 1) { int id = b->first_lir_instruction_id(); ResourceBitMap regs(FrameMap::nof_fpu_regs); iw.walk_to(id); // walk after the first instruction (always a label) of the block assert(iw.current_position() == id, "did not walk completely to id"); // Only consider FPU values in registers Interval* interval = iw.active_first(fixedKind); while (interval != Interval::end()) { int reg = interval->assigned_reg(); assert(reg >= pd_first_fpu_reg && reg <= pd_last_fpu_reg, "no fpu register"); assert(interval->assigned_regHi() == -1, "must not have hi register (doubles stored in one register)"); assert(interval->from() <= id && id < interval->to(), "interval out of range"); #ifndef PRODUCT if (TraceFPURegisterUsage) { tty->print("fpu reg %d is live because of ", reg - pd_first_fpu_reg); interval->print(); } #endif regs.set_bit(reg - pd_first_fpu_reg); interval = interval->next(); } b->set_fpu_register_usage(regs); #ifndef PRODUCT if (TraceFPURegisterUsage) { tty->print("FPU regs for block %d, LIR instr %d): ", b->block_id(), id); regs.print_on(tty); tty->cr(); } #endif } } } FpuStackAllocator alloc(ir()->compilation(), this); _fpu_stack_allocator = &alloc; alloc.allocate(); _fpu_stack_allocator = NULL; }