More aggressive constant propagation pass.
This commit is contained in:
parent
769b8d59d9
commit
f2348301ea
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue