More aggressive constant propagation pass.

This commit is contained in:
Ben Vanik 2013-12-15 14:40:18 -08:00
parent 769b8d59d9
commit f2348301ea
3 changed files with 118 additions and 1 deletions

View File

@ -48,6 +48,72 @@ int ConstantPropagationPass::Run(FunctionBuilder* builder) {
while (i) { while (i) {
Value* v = i->dest; Value* v = i->dest;
switch (i->opcode->num) { switch (i->opcode->num) {
case OPCODE_DEBUG_BREAK_TRUE:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantTrue()) {
i->Replace(&OPCODE_DEBUG_BREAK_info, i->flags);
} else {
i->Remove();
}
}
break;
case OPCODE_TRAP_TRUE:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantTrue()) {
i->Replace(&OPCODE_TRAP_info, i->flags);
} else {
i->Remove();
}
}
break;
case OPCODE_CALL_TRUE:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantTrue()) {
auto symbol_info = i->src2.symbol_info;
i->Replace(&OPCODE_CALL_info, i->flags);
i->src1.symbol_info = symbol_info;
} else {
i->Remove();
}
}
break;
case OPCODE_CALL_INDIRECT_TRUE:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantTrue()) {
auto value = i->src2.value;
i->Replace(&OPCODE_CALL_INDIRECT_info, i->flags);
i->set_src1(value);
} else {
i->Remove();
}
}
break;
case OPCODE_BRANCH_TRUE:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantTrue()) {
auto label = i->src2.label;
i->Replace(&OPCODE_BRANCH_info, i->flags);
i->src1.label = label;
} else {
i->Remove();
}
}
break;
case OPCODE_BRANCH_FALSE:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantFalse()) {
auto label = i->src2.label;
i->Replace(&OPCODE_BRANCH_info, i->flags);
i->src1.label = label;
} else {
i->Remove();
}
}
break;
case OPCODE_CAST: case OPCODE_CAST:
if (i->src1.value->IsConstant()) { if (i->src1.value->IsConstant()) {
TypeName target_type = v->type; TypeName target_type = v->type;
@ -81,6 +147,39 @@ int ConstantPropagationPass::Run(FunctionBuilder* builder) {
} }
break; break;
case OPCODE_SELECT:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantTrue()) {
v->set_from(i->src2.value);
} else {
v->set_from(i->src3.value);
}
i->Remove();
}
break;
case OPCODE_IS_TRUE:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantTrue()) {
v->set_constant((int8_t)1);
} else {
v->set_constant((int8_t)0);
}
i->Remove();
}
break;
case OPCODE_IS_FALSE:
if (i->src1.value->IsConstant()) {
if (i->src1.value->IsConstantFalse()) {
v->set_constant((int8_t)1);
} else {
v->set_constant((int8_t)0);
}
i->Remove();
}
break;
// TODO(benvanik): compares
case OPCODE_ADD: case OPCODE_ADD:
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
v->set_from(i->src1.value); v->set_from(i->src1.value);
@ -183,6 +282,7 @@ int ConstantPropagationPass::Run(FunctionBuilder* builder) {
i->Remove(); i->Remove();
} }
break; break;
// TODO(benvanik): VECTOR_SHL
case OPCODE_SHR: case OPCODE_SHR:
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
v->set_from(i->src1.value); v->set_from(i->src1.value);
@ -197,6 +297,7 @@ int ConstantPropagationPass::Run(FunctionBuilder* builder) {
i->Remove(); i->Remove();
} }
break; break;
// TODO(benvanik): ROTATE_LEFT
case OPCODE_BYTE_SWAP: case OPCODE_BYTE_SWAP:
if (i->src1.value->IsConstant()) { if (i->src1.value->IsConstant()) {
v->set_from(i->src1.value); v->set_from(i->src1.value);
@ -204,6 +305,13 @@ int ConstantPropagationPass::Run(FunctionBuilder* builder) {
i->Remove(); i->Remove();
} }
break; break;
// TODO(benvanik): INSERT/EXTRACT
// TODO(benvanik): SPLAT/PERMUTE/SWIZZLE
case OPCODE_SPLAT:
if (i->src1.value->IsConstant()) {
// Quite a few of these, from building vec128s.
}
break;
} }
i = i->next; i = i->next;
} }

View File

@ -48,7 +48,10 @@ void Instr::set_src3(Value* value) {
src3_use = value ? value->AddUse(block->arena, this) : NULL; src3_use = value ? value->AddUse(block->arena, this) : NULL;
} }
void Instr::Remove() { void Instr::Replace(const OpcodeInfo* opcode, uint16_t flags) {
this->opcode = opcode;
this->flags = flags;
if (dest) { if (dest) {
dest->def = NULL; dest->def = NULL;
} }
@ -64,6 +67,11 @@ void Instr::Remove() {
src3.value->RemoveUse(src3_use); src3.value->RemoveUse(src3_use);
src3_use = NULL; src3_use = NULL;
} }
}
void Instr::Remove() {
// Remove all srcs/dest.
Replace(&OPCODE_NOP_info, 0);
if (prev) { if (prev) {
prev->next = next; prev->next = next;

View File

@ -54,6 +54,7 @@ public:
void set_src2(Value* value); void set_src2(Value* value);
void set_src3(Value* value); void set_src3(Value* value);
void Replace(const OpcodeInfo* opcode, uint16_t flags);
void Remove(); void Remove();
}; };