Example #1
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);
    }
}