Skip to content
Snippets Groups Projects
Commit 643edd53 authored by COLLET Ismael's avatar COLLET Ismael
Browse files

upload files

parents
No related branches found
No related tags found
No related merge requests found
File added
// The name of a package is "coins.ssa"
package coins.ssa;
import coins.backend.LocalTransformer;
import coins.backend.Data;
import coins.backend.Function;
import coins.backend.cfg.BasicBlk;
import coins.backend.util.BiLink;
import coins.backend.lir.LirNode;
import coins.backend.lir.LirIconst;
import coins.backend.util.ImList;
import coins.backend.cfg.FlowGraph;
// Import coins.backend.Op, if you would like to refer kinds of operators.
import coins.backend.Op;
// Implement LocalTransformer
public class PeepHole implements LocalTransformer {
// Enable optimizations
public static final boolean ENABLE_ORIGINAL_OPT = false;
public static final boolean ENABLE_CONSTANT_FOLDING = false;
public static final boolean ENABLE_IF_WITH_CONSTANT = false;
public static final boolean ENABLE_REPLACE_X2_WITH_LEFT_SHIFT = true;
private SsaEnvironment env;
private SsaSymTab sstab;
public PeepHole(SsaEnvironment e, SsaSymTab tab) {
env = e;
sstab = tab;
}
public String name() { return "PeepHole"; }
public String subject() {
return "Simple optimizer using peephole approach";
}
public boolean doIt(Data data, ImList args) { return true; }
public boolean doIt(Function function,ImList args) {
// making a control graph.
FlowGraph flow = function.flowGraph();
for(BiLink bbl = flow.basicBlkList.first(); !bbl.atEnd(); bbl=bbl.next()){
BasicBlk bb=(BasicBlk)bbl.elem();
// Two continuous statements, "prevNode" and "node", are considered as a peephole,
// where prevNode records an immediately previous node of the node
BiLink prevNodel = null;
for(BiLink nodel=bb.instrList().first();!nodel.atEnd();
prevNodel = nodel, nodel = nodel.next()){
if (prevNodel != null) {
LirNode node = (LirNode)nodel.elem();
LirNode prevNode = (LirNode)prevNodel.elem();
if (ENABLE_ORIGINAL_OPT) {
// If the peephole matches a pattern:
// (SET (MEM x) (REG r)); (SET (REG r') (MEM x)), where
// a subexpression (MEM x) of prevNode has to correspond to one of the node,
// it can be transformed as follows:
// (SET (MEM x) (REG r)); (SET (REG r') (REG r))
if (node.opCode == Op.SET && prevNode.opCode == Op.SET &&
prevNode.kid(0).opCode == Op.MEM &&
(prevNode.kid(1).opCode == Op.REG ||
prevNode.kid(1).opCode == Op.INTCONST ||
prevNode.kid(1).opCode == Op.FLOATCONST) &&
node.kid(0).opCode == Op.REG && node.kid(1).opCode == Op.MEM &&
node.kid(1).equals(prevNode.kid(0))) {
// Printing a statement before transformation for confirmation
System.out.println(node.toString()+" is ");
// Transformation of node.
// The right-hand side is replaced with the left-hand side of prevNode.
// LirNode has a tree structure. ith child of a node can be extracted through
// node.kid(i), where i starts from 0.
// If you would like to replace ith child of a node with node',
// you can take advantage of node.setKid(i, node').
// At this time, you may not directly use a part of other LirNode as node'.
// Namely, node' has to be one copied from the part through makeCopy(env.lir).
node.setKid(1, prevNode.kid(1).makeCopy(env.lir));
// Printing a statement after transformation for confirmation
System.out.println("\treplaced with "+ node.toString());
}
}
if (ENABLE_CONSTANT_FOLDING){
// If the node matches a pattern:
// (SET (REG / MEM) (ADD (INTCONST) (INTCONST)))
// it can be transformed as follows:
// (SET (REG / MEM) (INTCONST))
// Also works for SUB MUL DIVS DIVU MODS MODU
if (node.opCode == Op.SET){
LirNode kidNode=node.kid(1);
if (kidNode.opCode == Op.ADD || kidNode.opCode == Op.SUB ||
kidNode.opCode == Op.MUL || kidNode.opCode == Op.DIVS || kidNode.opCode == Op.DIVU ||
kidNode.opCode == Op.MODS || kidNode.opCode == Op.MODU){
if (kidNode.kid(0).opCode == Op.INTCONST && kidNode.kid(1).opCode == Op.INTCONST){
int value1 = (int)((LirIconst)kidNode.kid(0)).value;
int value2 = (int)((LirIconst)kidNode.kid(1)).value;
int new_value=0;
if (kidNode.opCode == Op.ADD){
new_value = value1+value2;
} else if (kidNode.opCode == Op.SUB){
new_value = value1-value2;
} else if (kidNode.opCode == Op.MUL){
new_value = value1*value2;
} else if (kidNode.opCode == Op.DIVS || kidNode.opCode == Op.DIVU){
new_value = value1/value2;
} else if (kidNode.opCode == Op.MODS || kidNode.opCode == Op.MODU){
new_value = value1%value2;
}
LirNode new_node = env.lir.iconst(kidNode.kid(0).type, new_value);
node.setKid(1, new_node);
// Printing a statement after transformation for confirmation
System.out.println(kidNode.toString()+" is ");
System.out.println("\treplaced with "+ new_node.toString());
}
}
}
}
if (ENABLE_IF_WITH_CONSTANT){
// If the node matches a pattern:
// JUMPC ( TSTNE (INTCONST) (INTCONST)) (LABEL) (LABEL) )
// it can be transformed as follows:
// JUMP (LABEL)
// The label is selected according to the values of the INTCONSTs
if (node.opCode==Op.JUMPC && node.kid(0).opCode==Op.TSTNE &&
node.kid(0).kid(0).opCode==Op.INTCONST && node.kid(0).kid(1).opCode==Op.INTCONST){
// Printing a statement before transformation for confirmation
System.out.println(node.toString()+" is ");
int value1 = (int)((LirIconst)node.kid(0).kid(0)).value;
int value2 = (int)((LirIconst)node.kid(0).kid(1)).value;
// New jump node, intialized with the 2nd label
LirNode new_node=env.lir.operator(Op.JUMP, node.type, node.kid(2).makeCopy(env.lir), ImList.Empty);
if (value1!=value2){
new_node.setKid(0, node.kid(1).makeCopy(env.lir));
}
node=new_node;
// Printing a statement after transformation for confirmation
System.out.println("\treplaced with "+ new_node.toString());
}
}
if (ENABLE_REPLACE_X2_WITH_LEFT_SHIFT){
// If the node matches a pattern:
// (SET (REG x) (MUL (INTCONST 2) (REG x)))
// or (SET (REG x) (MUL (REG x) (INTCONST 2)))
// it can be transformed as follows:
// (LSHS (REG x))
if (node.opCode==Op.SET && node.kid(0).opCode==Op.REG && node.kid(1).opCode==Op.MUL && (
(node.kid(1).kid(1).opCode==Op.REG && node.kid(1).kid(1).equals(node.kid(0)) &&
node.kid(1).kid(0).opCode==Op.INTCONST && (int)((LirIconst)node.kid(1).kid(0)).value==2) ||
(node.kid(1).kid(0).opCode==Op.REG && node.kid(1).kid(0).equals(node.kid(0)) &&
node.kid(1).kid(1).opCode==Op.INTCONST && (int)((LirIconst)node.kid(1).kid(1)).value==2)
)){
// Printing a statement before transformation for confirmation
System.out.println(node.toString()+" is ");
node=env.lir.operator(Op.LSHS, node.type, node.kid(0).makeCopy(env.lir), ImList.Empty);
// Printing a statement after transformation for confirmation
System.out.println("\treplaced with "+ node.toString());
}
}
}
}
}
// If you have modified a control flow graph, you have to touch it.
flow.touch();
// The last of "doIt" returns true.
return(true);
}
}
#include<stdio.h>
main() {
int x, i;
x = 2+3;
printf("2+3=%d\n", x);
x = 2-3;
printf("2-3=%d\n", x);
x = 2*3;
printf("2x3=%d\n", x);
x = 32/3;
printf("32/3=%d\n", x);
x = 20%3;
printf("20%3=%d\n", x);
}
\ No newline at end of file
#include<stdio.h>
#define DEBUG_MODE 0
main() {
if (DEBUG_MODE){
printf("debug\n");
} else {
printf("not debug\n");
}
}
\ No newline at end of file
#include<stdio.h>
main() {
int x=1;
printf("x=%d\n", x);
x=2*x;
printf("x=2*x : %d\n", x);
x=x*2;
printf("x=x*2 : %d\n", x);
x=5*x;
printf("x=5*x : %d\n", x);
x=x*5;
printf("x=x*5 : %d\n", x);
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment