Make GVN aware of instructions that write to CPU flags.

This commit is contained in:
Dan Gohman
2017-10-19 12:57:55 -07:00
parent bce3c38042
commit cc0bb70c5d
4 changed files with 29 additions and 1 deletions

View File

@@ -23,3 +23,19 @@ ebb0:
v5 = iadd v4, v3
return v5
}
function %cpu_flags() -> b1 {
ebb0:
v0 = iconst.i32 7
v1 = iconst.i32 8
v2 = ifcmp v0, v1
v3 = trueif eq v2
v4 = ifcmp v0, v1
v5 = trueif eq v4
v6 = bor v3, v5
; check: v2 = ifcmp v0, v1
; check: v3 = trueif eq v2
; check: v4 = ifcmp v0, v1
; check: v5 = trueif eq v4
return v6
}

View File

@@ -110,6 +110,7 @@ class Instruction(object):
'can_trap': 'Can this instruction cause a trap?',
'other_side_effects':
'Does this instruction have other side effects besides can_*',
'writes_cpu_flags': 'Does this instruction write to CPU flags?',
}
def __init__(self, name, doc, ins=(), outs=(), constraints=(), **kwargs):
@@ -144,6 +145,10 @@ class Instruction(object):
"unknown instruction attribute '" + attr + "'")
for attr in Instruction.ATTRIBS:
setattr(self, attr, not not kwargs.get(attr, False))
# Infer the 'writes_cpu_flags' field value.
setattr(self, 'writes_cpu_flags', any(out.is_cpu_flags() for out in self.outs))
InstructionGroup.append(self)
def __str__(self):

View File

@@ -242,3 +242,10 @@ class Operand(object):
dependency.
"""
return self.kind is not VALUE and self.kind is not VARIABLE_ARGS
def is_cpu_flags(self):
# type: () -> bool
"""
Is this a CPU flags operand?
"""
return self.kind is VALUE and self.typevar.name in ['iflags', 'fflags']

View File

@@ -10,7 +10,7 @@ use scoped_hash_map::ScopedHashMap;
fn trivially_unsafe_for_gvn(opcode: Opcode) -> bool {
opcode.is_call() || opcode.is_branch() || opcode.is_terminator() ||
opcode.is_return() || opcode.can_trap() || opcode.other_side_effects() ||
opcode.can_store() || opcode.can_load()
opcode.can_store() || opcode.can_load() || opcode.writes_cpu_flags()
}
/// Perform simple GVN on `func`.