x = 5
y = x + 2
z = y * 3
x = 5
y = 5 + 2
z = y * 3
x = 5
y = 7
z = 7 * 3
x = 5
y = 7
z = 21
// Antes da otimização
int x = 5 * 60;
int y = 10 + 20 * 3;
double z = Math.PI * 2;
// Após Constant Folding
int x = 300;
int y = 70;
double z = 6.28318;
// Antes da otimização
a = b * c + d;
e = b * c * f;
// Após CSE
temp = b * c;
a = temp + d;
e = temp * f;
t1 = a + b
t2 = c * d
t3 = t1 + t2
t4 = e - f
t5 = g / h
// t3 e t5 nunca são usados
x = t4
// t1, t2, t3 são eliminados
// t5 é eliminado
t4 = e - f
x = t4
a = 5
b = 10
c = a
d = c + b
e = d * 2
a = 5
b = 10
c = 5
d = c + b
e = d * 2
a = 5
b = 10
c = 5
d = 5 + b
e = d * 2
a = 5
b = 10
c = 5
d = 5 + 10
e = d * 2
a = 5
b = 10
c = 5
d = 15
e = 30
t1 = 3.14159 * 2
t2 = 10 / 5
t3 = t1 * (4 * 4)
t4 = t3 + t2
if (5 > 3) goto L1
goto L2
L1: x = 10
L2: y = 20
t1 = 6.28318
t2 = 2
t3 = 100.53088
t4 = 102.53088
goto L1
L1: x = 10
L2: y = 20
a[i] = b[i] * (c[i] + d[i])
e[i] = (c[i] + d[i]) * 2
temp = c[i] + d[i]
a[i] = b[i] * temp
e[i] = temp * 2
// Cálculo do perímetro e área de um retângulo
a = 5
b = 7
p1 = 2 * a
p2 = 2 * b
perimetro = p1 + p2
area = a * b
diagonal = sqrt(a*a + b*b)
area2 = a * b // Redundante
a = 5
b = 7
p1 = 2 * a
p2 = 2 * b
perimetro = p1 + p2
area = a * b
diagonal = sqrt(a*a + b*b)
area2 = area // Reutilização do cálculo
// Cálculo de juros compostos
principal = 1000
taxa = 0.05
tempo = 3
t1 = 1 + taxa
t2 = t1 ^ tempo
montante = principal * t2
principal = 1000
taxa = 0.05
tempo = 3
t1 = 1.05
t2 = 1.157625 // 1.05^3
montante = 1157.625 // 1000 * 1.157625
a = 3
b = 2
c = a + b
d = c * 2
e = a + b
f = e + d
a = 3
b = 2
c = 3 + 2
d = c * 2
e = 3 + 2
f = e + d
a = 3
b = 2
c = 5
d = c * 2
e = 5
f = e + d
a = 3
b = 2
c = 5
d = c * 2
e = c // Reutiliza c em vez de recalcular
f = e + d
a = 3
b = 2
c = 5
d = 10
e = 5
f = 15
import ast
class ConstantFolder(ast.NodeTransformer):
def visit_BinOp(self, node):
node = self.generic_visit(node)
if isinstance(node.left, ast.Constant) and \
isinstance(node.right, ast.Constant):
# Simplificar operações entre constantes
...
import ast
import operator
class ConstantFolder(ast.NodeTransformer):
def visit_BinOp(self, node):
# Primeiro, processe recursivamente os nós filhos
node = self.generic_visit(node)
# Verifique se ambos operandos são constantes
if isinstance(node.left, ast.Constant) and isinstance(node.right, ast.Constant):
# Mapeamento de operadores para funções do Python
op_func = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.truediv
}
if type(node.op) in op_func:
try:
# Calcule o resultado da operação
result = op_func[type(node.op)](node.left.value, node.right.value)
# Retorne um nó constante com o resultado
return ast.Constant(value=result)
except:
# Em caso de erro (divisão por zero, etc.), mantenha o nó original
pass
return node
def eliminar_codigo_morto(codigo_tac):
# Passo 1: Identificar variáveis utilizadas
variaveis_usadas = set()
# Percorre o código de baixo para cima
for i in range(len(codigo_tac) - 1, -1, -1):
instrucao = codigo_tac[i]
# Analisa uso de variáveis na instrução atual
vars_usadas_instr = obter_vars_usadas(instrucao)
variaveis_usadas.update(vars_usadas_instr)
# Se a instrução define uma variável não usada,
# marca para remoção
if eh_atribuicao(instrucao):
var_definida = obter_var_definida(instrucao)
if var_definida not in variaveis_usadas:
instrucao['remover'] = True
else:
# Remove da lista após encontrar sua definição
variaveis_usadas.remove(var_definida)
# Passo 2: Remover instruções marcadas
codigo_otimizado = []
for instrucao in codigo_tac:
if not instrucao.get('remover', False):
codigo_otimizado.append(instrucao)
return codigo_otimizado
# Funções auxiliares
def obter_vars_usadas(instrucao):
# Extrai variáveis usadas no lado direito da instrução
# ...
def eh_atribuicao(instrucao):
# Verifica se a instrução é uma atribuição
# ...
def obter_var_definida(instrucao):
# Obtém a variável definida no lado esquerdo
# ...
t1 = 5
t2 = 3
t3 = t1 + t2
t4 = t1 + t2
t5 = t4 * 2
t6 = t3 * t3
t7 = t5 + 10
t8 = t7 // Nunca usado
resultado = t6
t1 = 5
t2 = 3
t3 = 8
t6 = 64
resultado = 64
a = 10
b = 20
c = a + b
d = 30
e = c + d
f = a + b
g = f + d
h = e * 2
i = g * 2
j = i - h
if (1 > 0):
k = 100
else:
k = 200
l = j + k