size_t MemoryValue::accessByteSize() const { switch (opcode()) { case Load8Z: case Load8S: case Store8: return 1; case Load16Z: case Load16S: case Store16: return 2; case Load: return sizeofType(type()); case Store: return sizeofType(child(0)->type()); default: RELEASE_ASSERT_NOT_REACHED(); return 0; } }
void demoteValues(Procedure& proc, const IndexSet<Value>& values) { HashMap<Value*, StackSlotValue*> map; HashMap<Value*, StackSlotValue*> phiMap; // Create stack slots. InsertionSet insertionSet(proc); for (Value* value : values.values(proc.values())) { StackSlotValue* stack = insertionSet.insert<StackSlotValue>( 0, value->origin(), sizeofType(value->type()), StackSlotKind::Anonymous); map.add(value, stack); if (value->opcode() == Phi) { StackSlotValue* phiStack = insertionSet.insert<StackSlotValue>( 0, value->origin(), sizeofType(value->type()), StackSlotKind::Anonymous); phiMap.add(value, phiStack); } } insertionSet.execute(proc[0]); if (verbose) { dataLog("Demoting values as follows:\n"); dataLog(" map = "); CommaPrinter comma; for (auto& entry : map) dataLog(comma, *entry.key, "=>", *entry.value); dataLog("\n"); dataLog(" phiMap = "); comma = CommaPrinter(); for (auto& entry : phiMap) dataLog(comma, *entry.key, "=>", *entry.value); dataLog("\n"); } // Change accesses to the values to accesses to the stack slots. for (BasicBlock* block : proc) { for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) { Value* value = block->at(valueIndex); if (value->opcode() == Phi) { if (StackSlotValue* stack = phiMap.get(value)) { value->replaceWithIdentity( insertionSet.insert<MemoryValue>( valueIndex, Load, value->type(), value->origin(), stack)); } } else { for (Value*& child : value->children()) { if (StackSlotValue* stack = map.get(child)) { child = insertionSet.insert<MemoryValue>( valueIndex, Load, child->type(), value->origin(), stack); } } if (UpsilonValue* upsilon = value->as<UpsilonValue>()) { if (StackSlotValue* stack = phiMap.get(upsilon->phi())) { insertionSet.insert<MemoryValue>( valueIndex, Store, upsilon->origin(), upsilon->child(0), stack); value->replaceWithNop(); } } } if (StackSlotValue* stack = map.get(value)) { insertionSet.insert<MemoryValue>( valueIndex + 1, Store, value->origin(), value, stack); } } insertionSet.execute(block); } }