Using boost now
This commit is contained in:
parent
a740690e04
commit
4dd97b0709
@ -5,6 +5,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <llvm/ADT/ilist.h>
|
#include <llvm/ADT/ilist.h>
|
||||||
#include <llvm/ADT/ilist_node.h>
|
#include <llvm/ADT/ilist_node.h>
|
||||||
|
#include <boost/range.hpp>
|
||||||
|
#include "icode.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
//#include "icode.h"
|
//#include "icode.h"
|
||||||
@ -12,22 +14,21 @@
|
|||||||
struct Function;
|
struct Function;
|
||||||
class CIcodeRec;
|
class CIcodeRec;
|
||||||
struct BB;
|
struct BB;
|
||||||
|
struct LOCAL_ID;
|
||||||
struct interval;
|
struct interval;
|
||||||
struct ICODE;
|
|
||||||
typedef std::list<ICODE>::iterator iICODE;
|
struct TYPEADR_TYPE
|
||||||
typedef std::list<ICODE>::reverse_iterator riICODE;
|
|
||||||
typedef union
|
|
||||||
{
|
{
|
||||||
uint32_t ip; /* Out edge icode address */
|
uint32_t ip; /* Out edge icode address */
|
||||||
BB * BBptr; /* Out edge pointer to next BB */
|
BB * BBptr; /* Out edge pointer to next BB */
|
||||||
interval *intPtr; /* Out edge ptr to next interval*/
|
interval *intPtr; /* Out edge ptr to next interval*/
|
||||||
} TYPEADR_TYPE;
|
};
|
||||||
|
|
||||||
struct BB : public llvm::ilist_node<BB>
|
struct BB : public llvm::ilist_node<BB>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
BB(const BB&);
|
BB(const BB&);
|
||||||
BB() : nodeType(0),traversed(0),
|
BB() : nodeType(0),traversed(DFS_NONE),
|
||||||
numHlIcodes(0),flg(0),
|
numHlIcodes(0),flg(0),
|
||||||
inEdges(0),
|
inEdges(0),
|
||||||
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
||||||
@ -38,10 +39,14 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
//friend class SymbolTableListTraits<BB, Function>;
|
//friend class SymbolTableListTraits<BB, Function>;
|
||||||
iICODE range_start;
|
typedef boost::iterator_range<iICODE> rCODE;
|
||||||
iICODE range_end;
|
rCODE instructions;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
struct ValidFunctor
|
||||||
|
{
|
||||||
|
bool operator()(BB *p) {return p->valid();}
|
||||||
|
};
|
||||||
iICODE begin();
|
iICODE begin();
|
||||||
iICODE end() const;
|
iICODE end() const;
|
||||||
riICODE rbegin();
|
riICODE rbegin();
|
||||||
@ -50,7 +55,7 @@ public:
|
|||||||
ICODE &back();
|
ICODE &back();
|
||||||
size_t size();
|
size_t size();
|
||||||
uint8_t nodeType; /* Type of node */
|
uint8_t nodeType; /* Type of node */
|
||||||
int traversed; /* Boolean: traversed yet? */
|
eDFS traversed; /* last traversal id is held here traversed yet? */
|
||||||
int numHlIcodes; /* No. of high-level icodes */
|
int numHlIcodes; /* No. of high-level icodes */
|
||||||
uint32_t flg; /* BB flags */
|
uint32_t flg; /* BB flags */
|
||||||
|
|
||||||
@ -94,8 +99,9 @@ public:
|
|||||||
int caseTail; /* tail node for the case */
|
int caseTail; /* tail node for the case */
|
||||||
|
|
||||||
int index; /* Index, used in several ways */
|
int index; /* Index, used in several ways */
|
||||||
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
|
static BB * Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
|
||||||
static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent);
|
static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent);
|
||||||
|
static BB * Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent);
|
||||||
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
|
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
|
||||||
void mergeFallThrough(CIcodeRec &Icode);
|
void mergeFallThrough(CIcodeRec &Icode);
|
||||||
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
|
void dfsNumbering(std::vector<BB *> &dfsLast, int *first, int *last);
|
||||||
@ -105,10 +111,19 @@ static BB * Create(int start, int ip, uint8_t nodeType, int numOutEdges, Functio
|
|||||||
///
|
///
|
||||||
const Function *getParent() const { return Parent; }
|
const Function *getParent() const { return Parent; }
|
||||||
Function *getParent() { return Parent; }
|
Function *getParent() { return Parent; }
|
||||||
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
|
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
|
||||||
BB *rmJMP(int marker, BB *pBB);
|
BB * rmJMP(int marker, BB *pBB);
|
||||||
void genDU1();
|
void genDU1();
|
||||||
|
int findBBExps(LOCAL_ID &locals, Function *f);
|
||||||
|
bool valid() {return 0==(flg & INVALID_BB); }
|
||||||
|
bool wasTraversedAtLevel(int l) const {return traversed==l;}
|
||||||
|
ICODE * writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond);
|
||||||
|
void addOutEdge(uint32_t ip) // TODO: fix this
|
||||||
|
{
|
||||||
|
edges[0].ip = ip;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
|
bool isEndOfPath(int latch_node_idx) const;
|
||||||
Function *Parent;
|
Function *Parent;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -124,6 +124,9 @@ public:
|
|||||||
r->name = nm;
|
r->name = nm;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
bool anyFlagsSet(uint32_t t) { return (flg&t)!=0;}
|
||||||
|
bool hasRegArgs() const { return (flg & REG_ARGS)!=0;}
|
||||||
|
bool isLibrary() const { return (flg & PROC_ISLIB)!=0;}
|
||||||
void compoundCond();
|
void compoundCond();
|
||||||
void writeProcComments();
|
void writeProcComments();
|
||||||
void lowLevelAnalysis();
|
void lowLevelAnalysis();
|
||||||
@ -140,10 +143,8 @@ public:
|
|||||||
void process_operands(ICODE &pIcode, STATE *pstate);
|
void process_operands(ICODE &pIcode, STATE *pstate);
|
||||||
boolT process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
boolT process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
|
||||||
boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
void displayCFG();
|
|
||||||
void freeCFG();
|
void freeCFG();
|
||||||
void codeGen(std::ostream &fs);
|
void codeGen(std::ostream &fs);
|
||||||
void displayStats();
|
|
||||||
void mergeFallThrough(BB *pBB);
|
void mergeFallThrough(BB *pBB);
|
||||||
void structIfs();
|
void structIfs();
|
||||||
void structLoops(derSeq *derivedG);
|
void structLoops(derSeq *derivedG);
|
||||||
@ -151,20 +152,25 @@ public:
|
|||||||
void controlFlowAnalysis();
|
void controlFlowAnalysis();
|
||||||
void newRegArg(iICODE picode, iICODE ticode);
|
void newRegArg(iICODE picode, iICODE ticode);
|
||||||
void writeProcComments(std::ostream &ostr);
|
void writeProcComments(std::ostream &ostr);
|
||||||
|
|
||||||
|
void displayCFG();
|
||||||
|
void displayStats();
|
||||||
|
void processHliCall(COND_EXPR *exp, iICODE picode);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b);
|
||||||
bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
bool Case_X_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
||||||
bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
bool Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
||||||
bool Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
bool Case_notX_or_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
||||||
bool Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
bool Case_notX_and_Y(BB* pbb, BB* thenBB, BB* elseBB);
|
||||||
void replaceInEdge(BB* where, BB* which, BB* with);
|
void replaceInEdge(BB* where, BB* which, BB* with);
|
||||||
protected:
|
void processExpPush(int &numHlIcodes, iICODE picode);
|
||||||
bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b);
|
|
||||||
|
|
||||||
// TODO: replace those with friend visitor ?
|
// TODO: replace those with friend visitor ?
|
||||||
void propLongReg(int loc_ident_idx, const ID &pLocId);
|
void propLongReg(int loc_ident_idx, const ID &pLocId);
|
||||||
void propLongStk(int i, const ID &pLocId);
|
void propLongStk(int i, const ID &pLocId);
|
||||||
void propLongGlb(int i, const ID &pLocId);
|
void propLongGlb(int i, const ID &pLocId);
|
||||||
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong);
|
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong);
|
||||||
void processHliCall(COND_EXPR *exp, iICODE picode);
|
|
||||||
|
|
||||||
int findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE iter);
|
int findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE iter);
|
||||||
int findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg);
|
int findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg);
|
||||||
@ -176,6 +182,6 @@ public:
|
|||||||
void findIdioms();
|
void findIdioms();
|
||||||
void propLong();
|
void propLong();
|
||||||
void genLiveKtes();
|
void genLiveKtes();
|
||||||
uint8_t findDerivedSeq (derSeq &derivedGi);
|
uint8_t findDerivedSeq (derSeq &derivedGi);
|
||||||
bool nextOrderGraph(derSeq &derivedGi);
|
bool nextOrderGraph(derSeq &derivedGi);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -85,7 +85,7 @@ public:
|
|||||||
static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
|
static COND_EXPR * id(const LLInst &ll_insn, opLoc sd, Function *pProc, iICODE ix_, ICODE &duIcode, operDu du);
|
||||||
static COND_EXPR *boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op);
|
static COND_EXPR *boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op);
|
||||||
static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx);
|
static bool insertSubTreeLongReg(COND_EXPR *exp, COND_EXPR **tree, int longIdx);
|
||||||
static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym);
|
static bool insertSubTreeReg(COND_EXPR *&tree, COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
public:
|
public:
|
||||||
virtual COND_EXPR *clone() const;
|
virtual COND_EXPR *clone() const;
|
||||||
void release();
|
void release();
|
||||||
@ -105,8 +105,8 @@ public:
|
|||||||
virtual ~COND_EXPR() {}
|
virtual ~COND_EXPR() {}
|
||||||
public:
|
public:
|
||||||
virtual COND_EXPR *inverse() const; // return new COND_EXPR that is invarse of this
|
virtual COND_EXPR *inverse() const; // return new COND_EXPR that is invarse of this
|
||||||
virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc);
|
virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locId);
|
||||||
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym);
|
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
|
||||||
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
|
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
|
||||||
virtual hlType expType(Function *pproc) const;
|
virtual hlType expType(Function *pproc) const;
|
||||||
};
|
};
|
||||||
@ -124,7 +124,7 @@ struct BinaryOperator : public COND_EXPR
|
|||||||
static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r);
|
static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r);
|
||||||
virtual COND_EXPR *inverse();
|
virtual COND_EXPR *inverse();
|
||||||
virtual COND_EXPR *clone();
|
virtual COND_EXPR *clone();
|
||||||
virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc);
|
virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locs);
|
||||||
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym);
|
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym);
|
||||||
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
|
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ struct UnaryOperator : public COND_EXPR
|
|||||||
COND_EXPR *unaryExp;
|
COND_EXPR *unaryExp;
|
||||||
virtual COND_EXPR *inverse();
|
virtual COND_EXPR *inverse();
|
||||||
virtual COND_EXPR *clone();
|
virtual COND_EXPR *clone();
|
||||||
virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc);
|
virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locs);
|
||||||
static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr)
|
static UnaryOperator *Create(condNodeType t, COND_EXPR *sub_expr)
|
||||||
{
|
{
|
||||||
UnaryOperator *newExp = new UnaryOperator();
|
UnaryOperator *newExp = new UnaryOperator();
|
||||||
|
|||||||
@ -30,6 +30,7 @@ public:
|
|||||||
}
|
}
|
||||||
strTable decl; /* Declarations */
|
strTable decl; /* Declarations */
|
||||||
strTable code; /* C code */
|
strTable code; /* C code */
|
||||||
|
int current_indent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@ enum eBBKind
|
|||||||
/* Depth-first traversal constants */
|
/* Depth-first traversal constants */
|
||||||
enum eDFS
|
enum eDFS
|
||||||
{
|
{
|
||||||
|
DFS_NONE,
|
||||||
DFS_DISP=1, /* Display graph pass */
|
DFS_DISP=1, /* Display graph pass */
|
||||||
DFS_MERGE=2, /* Merge nodes pass */
|
DFS_MERGE=2, /* Merge nodes pass */
|
||||||
DFS_NUM=3, /* DFS numbering pass */
|
DFS_NUM=3, /* DFS numbering pass */
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
#include <llvm/MC/MCInst.h>
|
#include <llvm/MC/MCInst.h>
|
||||||
#include <llvm/MC/MCAsmInfo.h>
|
#include <llvm/MC/MCAsmInfo.h>
|
||||||
#include <llvm/Value.h>
|
#include <llvm/Value.h>
|
||||||
|
#include <boost/range.hpp>
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
||||||
//enum condId;
|
//enum condId;
|
||||||
@ -26,6 +27,7 @@ struct ICODE;
|
|||||||
struct bundle;
|
struct bundle;
|
||||||
typedef std::list<ICODE>::iterator iICODE;
|
typedef std::list<ICODE>::iterator iICODE;
|
||||||
typedef std::list<ICODE>::reverse_iterator riICODE;
|
typedef std::list<ICODE>::reverse_iterator riICODE;
|
||||||
|
typedef boost::iterator_range<iICODE> rCODE;
|
||||||
|
|
||||||
/* uint8_t and uint16_t registers */
|
/* uint8_t and uint16_t registers */
|
||||||
|
|
||||||
@ -58,6 +60,7 @@ struct CallType : public HlTypeSupport
|
|||||||
void allocStkArgs (int num);
|
void allocStkArgs (int num);
|
||||||
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc);
|
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc);
|
||||||
void placeStkArg(COND_EXPR *exp, int pos);
|
void placeStkArg(COND_EXPR *exp, int pos);
|
||||||
|
virtual COND_EXPR * toId();
|
||||||
public:
|
public:
|
||||||
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
|
||||||
{
|
{
|
||||||
@ -285,6 +288,18 @@ protected:
|
|||||||
HLTYPE m_hl;
|
HLTYPE m_hl;
|
||||||
bool invalid; /* Has no HIGH_LEVEL equivalent */
|
bool invalid; /* Has no HIGH_LEVEL equivalent */
|
||||||
public:
|
public:
|
||||||
|
template<int FLAG>
|
||||||
|
struct FlagFilter
|
||||||
|
{
|
||||||
|
bool operator()(ICODE *ic) {return ic->ll()->testFlags(FLAG);}
|
||||||
|
bool operator()(ICODE &ic) {return ic.ll()->testFlags(FLAG);}
|
||||||
|
};
|
||||||
|
template<int TYPE>
|
||||||
|
struct TypeFilter
|
||||||
|
{
|
||||||
|
bool operator()(ICODE *ic) {return ic->type==HIGH_LEVEL;}
|
||||||
|
bool operator()(ICODE &ic) {return ic.type==HIGH_LEVEL;}
|
||||||
|
};
|
||||||
/* Def/Use of registers and stack variables */
|
/* Def/Use of registers and stack variables */
|
||||||
struct DU_ICODE
|
struct DU_ICODE
|
||||||
{
|
{
|
||||||
@ -399,6 +414,7 @@ public:
|
|||||||
|
|
||||||
ICODE * addIcode(ICODE *pIcode);
|
ICODE * addIcode(ICODE *pIcode);
|
||||||
void SetInBB(int start, int end, BB* pnewBB);
|
void SetInBB(int start, int end, BB* pnewBB);
|
||||||
|
void SetInBB(rCODE &rang, BB* pnewBB);
|
||||||
bool labelSrch(uint32_t target, uint32_t &pIndex);
|
bool labelSrch(uint32_t target, uint32_t &pIndex);
|
||||||
iterator labelSrch(uint32_t target);
|
iterator labelSrch(uint32_t target);
|
||||||
ICODE * GetIcode(int ip);
|
ICODE * GetIcode(int ip);
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
/* Type definition */
|
/* Type definition */
|
||||||
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
|
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
|
||||||
// TODO: why ?
|
// TODO: why ?
|
||||||
|
struct COND_EXPR;
|
||||||
struct ICODE;
|
struct ICODE;
|
||||||
typedef std::list<ICODE>::iterator iICODE;
|
typedef std::list<ICODE>::iterator iICODE;
|
||||||
struct IDX_ARRAY : public std::vector<iICODE>
|
struct IDX_ARRAY : public std::vector<iICODE>
|
||||||
@ -104,6 +105,10 @@ struct ID
|
|||||||
struct LOCAL_ID
|
struct LOCAL_ID
|
||||||
{
|
{
|
||||||
std::vector<ID> id_arr;
|
std::vector<ID> id_arr;
|
||||||
|
protected:
|
||||||
|
int newLongIdx(int16_t seg, int16_t offH, int16_t offL, uint8_t regi, hlType t);
|
||||||
|
int newLongGlb(int16_t seg, int16_t offH, int16_t offL, hlType t);
|
||||||
|
int newLongStk(hlType t, int offH, int offL);
|
||||||
public:
|
public:
|
||||||
LOCAL_ID()
|
LOCAL_ID()
|
||||||
{
|
{
|
||||||
@ -122,10 +127,10 @@ public:
|
|||||||
void flagByteWordId(int off);
|
void flagByteWordId(int off);
|
||||||
void propLongId(uint8_t regL, uint8_t regH, const char *name);
|
void propLongId(uint8_t regL, uint8_t regH, const char *name);
|
||||||
size_t csym() const {return id_arr.size();}
|
size_t csym() const {return id_arr.size();}
|
||||||
protected:
|
void newRegArg(iICODE picode, iICODE ticode) const;
|
||||||
int newLongIdx(int16_t seg, int16_t offH, int16_t offL, uint8_t regi, hlType t);
|
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
|
||||||
int newLongGlb(int16_t seg, int16_t offH, int16_t offL, hlType t);
|
void forwardSubs(COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
|
||||||
int newLongStk(hlType t, int offH, int offL);
|
COND_EXPR *createId(const ID *retVal, iICODE ix_);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ struct STKSYM : public SymbolCommon
|
|||||||
void setArgName(int i)
|
void setArgName(int i)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
sprintf (buf, "arg%ld", i);
|
sprintf (buf, "arg%d", i);
|
||||||
name = buf;
|
name = buf;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <boost/range/rbegin.hpp>
|
||||||
|
#include <boost/range/rend.hpp>
|
||||||
|
#include <boost/range/adaptors.hpp>
|
||||||
#include "BasicBlock.h"
|
#include "BasicBlock.h"
|
||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace boost;
|
||||||
|
|
||||||
BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore)
|
BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore)
|
||||||
{
|
{
|
||||||
@ -12,29 +15,27 @@ BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore)
|
|||||||
pnewBB->Parent = parent;
|
pnewBB->Parent = parent;
|
||||||
return pnewBB;
|
return pnewBB;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *parent)
|
* @arg start - basic block starts here, might be parent->Icode.end()
|
||||||
|
* @arg fin - last of basic block's instructions
|
||||||
|
*/
|
||||||
|
BB *BB::Create(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent)
|
||||||
{
|
{
|
||||||
BB* pnewBB;
|
BB* pnewBB;
|
||||||
|
|
||||||
pnewBB = new BB;
|
pnewBB = new BB;
|
||||||
pnewBB->nodeType = _nodeType; /* Initialise */
|
pnewBB->nodeType = _nodeType; /* Initialise */
|
||||||
pnewBB->immedDom = NO_DOM;
|
pnewBB->immedDom = NO_DOM;
|
||||||
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
|
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
|
||||||
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
|
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
|
||||||
pnewBB->range_start = parent->Icode.begin();
|
pnewBB->instructions = make_iterator_range(start,fin);
|
||||||
pnewBB->range_end = parent->Icode.begin();
|
if(start==parent->Icode.end())
|
||||||
if(start!=-1)
|
|
||||||
{
|
{
|
||||||
advance(pnewBB->range_start,start);
|
pnewBB->instructions = make_iterator_range(parent->Icode.end(),parent->Icode.end());
|
||||||
advance(pnewBB->range_end,ip+1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pnewBB->range_end = parent->Icode.end();
|
pnewBB->instructions.advance_end(1); // 1 after fin, to create range where fin is inclusive
|
||||||
pnewBB->range_end = parent->Icode.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOutEdges)
|
if (numOutEdges)
|
||||||
pnewBB->edges.resize(numOutEdges);
|
pnewBB->edges.resize(numOutEdges);
|
||||||
|
|
||||||
@ -42,16 +43,32 @@ BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *
|
|||||||
* real code basic blocks (ie. not interval bbs) */
|
* real code basic blocks (ie. not interval bbs) */
|
||||||
if(parent)
|
if(parent)
|
||||||
{
|
{
|
||||||
if (start >= 0)
|
if (start != parent->Icode.end())
|
||||||
parent->Icode.SetInBB(start, ip, pnewBB);
|
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
||||||
parent->heldBBs.push_back(pnewBB);
|
parent->heldBBs.push_back(pnewBB);
|
||||||
parent->m_cfg.push_back(pnewBB);
|
parent->m_cfg.push_back(pnewBB);
|
||||||
pnewBB->Parent = parent;
|
pnewBB->Parent = parent;
|
||||||
}
|
}
|
||||||
if (start != -1) /* Only for code BB's */
|
if ( start != parent->Icode.end() ) /* Only for code BB's */
|
||||||
stats.numBBbef++;
|
stats.numBBbef++;
|
||||||
return pnewBB;
|
return pnewBB;
|
||||||
}
|
}
|
||||||
|
BB *BB::Create(int start, int ip, uint8_t _nodeType, int numOutEdges, Function *parent)
|
||||||
|
{
|
||||||
|
iICODE st(parent->Icode.begin());
|
||||||
|
iICODE fin(parent->Icode.begin());
|
||||||
|
if(start==-1)
|
||||||
|
{
|
||||||
|
st = parent->Icode.end();
|
||||||
|
fin = parent->Icode.end();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
advance(st,start);
|
||||||
|
advance(fin,ip);
|
||||||
|
}
|
||||||
|
return Create(st,fin,_nodeType,numOutEdges,parent);
|
||||||
|
}
|
||||||
|
|
||||||
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
|
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
|
||||||
"loop", "repeat", "interval", "cycleHead",
|
"loop", "repeat", "interval", "cycleHead",
|
||||||
@ -67,7 +84,12 @@ void BB::display()
|
|||||||
printf("start = %ld, length = %ld, #out edges = %ld\n", begin()->loc_ip, size(), edges.size());
|
printf("start = %ld, length = %ld, #out edges = %ld\n", begin()->loc_ip, size(), edges.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < edges.size(); i++)
|
for (size_t i = 0; i < edges.size(); i++)
|
||||||
printf(" outEdge[%2d] = %ld\n",i, edges[i].BBptr->begin()->loc_ip);
|
{
|
||||||
|
if(edges[i].BBptr==0)
|
||||||
|
printf(" outEdge[%2d] = Unlinked out edge to %d\n",i, edges[i].ip);
|
||||||
|
else
|
||||||
|
printf(" outEdge[%2d] = %d\n",i, edges[i].BBptr->begin()->loc_ip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* displayDfs - Displays the CFG using a depth first traversal
|
* displayDfs - Displays the CFG using a depth first traversal
|
||||||
@ -131,11 +153,63 @@ void BB::displayDfs()
|
|||||||
* current procedure.
|
* current procedure.
|
||||||
* indLevel: indentation level - used for formatting.
|
* indLevel: indentation level - used for formatting.
|
||||||
* numLoc: last # assigned to local variables */
|
* numLoc: last # assigned to local variables */
|
||||||
|
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond)
|
||||||
|
{
|
||||||
|
latch = pProc->m_dfsLast[this->latchNode];
|
||||||
|
std::ostringstream ostr;
|
||||||
|
ICODE* picode;
|
||||||
|
switch (loopType)
|
||||||
|
{
|
||||||
|
case WHILE_TYPE:
|
||||||
|
picode = &this->back();
|
||||||
|
|
||||||
|
/* Check for error in while condition */
|
||||||
|
if (picode->hl()->opcode != HLI_JCOND)
|
||||||
|
reportError (WHILE_FAIL);
|
||||||
|
|
||||||
|
/* Check if condition is more than 1 HL instruction */
|
||||||
|
if (numHlIcodes > 1)
|
||||||
|
{
|
||||||
|
/* Write the code for this basic block */
|
||||||
|
writeBB(ostr,indLevel, pProc, numLoc);
|
||||||
|
repCond = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Condition needs to be inverted if the loop body is along
|
||||||
|
* the THEN path of the header node */
|
||||||
|
if (edges[ELSE].BBptr->dfsLastNum == loopFollow)
|
||||||
|
{
|
||||||
|
picode->hl()->replaceExpr(picode->hl()->expr()->inverse());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc);
|
||||||
|
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
|
||||||
|
}
|
||||||
|
picode->invalidate();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REPEAT_TYPE:
|
||||||
|
ostr << "\n"<<indentStr(indLevel)<<"do {\n";
|
||||||
|
picode = &latch->back();
|
||||||
|
picode->invalidate();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENDLESS_TYPE:
|
||||||
|
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
|
||||||
|
}
|
||||||
|
cCode.appendCode(ostr.str());
|
||||||
|
stats.numHLIcode += 1;
|
||||||
|
indLevel++;
|
||||||
|
return picode;
|
||||||
|
}
|
||||||
|
bool BB::isEndOfPath(int latch_node_idx) const
|
||||||
|
{
|
||||||
|
return nodeType == RETURN_NODE || nodeType == TERMINATE_NODE ||
|
||||||
|
nodeType == NOWHERE_NODE || (dfsLastNum == latch_node_idx);
|
||||||
|
}
|
||||||
void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, int _ifFollow)
|
void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, int _ifFollow)
|
||||||
{
|
{
|
||||||
int follow, /* ifFollow */
|
int follow; /* ifFollow */
|
||||||
_loopType, /* Type of loop, if any */
|
|
||||||
_nodeType; /* Type of node */
|
|
||||||
BB * succ, *latch; /* Successor and latching node */
|
BB * succ, *latch; /* Successor and latching node */
|
||||||
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
||||||
char *l; /* Pointer to HLI_JCOND expression */
|
char *l; /* Pointer to HLI_JCOND expression */
|
||||||
@ -146,60 +220,16 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
if ((_ifFollow != UN_INIT) && (this == pProc->m_dfsLast[_ifFollow]))
|
if ((_ifFollow != UN_INIT) && (this == pProc->m_dfsLast[_ifFollow]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (traversed == DFS_ALPHA)
|
if (wasTraversedAtLevel(DFS_ALPHA))
|
||||||
return;
|
return;
|
||||||
traversed = DFS_ALPHA;
|
traversed = DFS_ALPHA;
|
||||||
|
|
||||||
/* Check for start of loop */
|
/* Check for start of loop */
|
||||||
repCond = false;
|
repCond = false;
|
||||||
latch = NULL;
|
latch = NULL;
|
||||||
_loopType = loopType;
|
if (loopType)
|
||||||
if (_loopType)
|
|
||||||
{
|
{
|
||||||
latch = pProc->m_dfsLast[this->latchNode];
|
picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond);
|
||||||
std::ostringstream ostr;
|
|
||||||
switch (_loopType)
|
|
||||||
{
|
|
||||||
case WHILE_TYPE:
|
|
||||||
picode = &this->back();
|
|
||||||
|
|
||||||
/* Check for error in while condition */
|
|
||||||
if (picode->hl()->opcode != HLI_JCOND)
|
|
||||||
reportError (WHILE_FAIL);
|
|
||||||
|
|
||||||
/* Check if condition is more than 1 HL instruction */
|
|
||||||
if (numHlIcodes > 1)
|
|
||||||
{
|
|
||||||
/* Write the code for this basic block */
|
|
||||||
writeBB(ostr,indLevel, pProc, numLoc);
|
|
||||||
repCond = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Condition needs to be inverted if the loop body is along
|
|
||||||
* the THEN path of the header node */
|
|
||||||
if (edges[ELSE].BBptr->dfsLastNum == loopFollow)
|
|
||||||
{
|
|
||||||
picode->hl()->replaceExpr(picode->hl()->expr()->inverse());
|
|
||||||
}
|
|
||||||
{
|
|
||||||
string e=walkCondExpr (picode->hl()->expr(), pProc, numLoc);
|
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"while ("<<e<<") {\n";
|
|
||||||
}
|
|
||||||
picode->invalidate();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case REPEAT_TYPE:
|
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"do {\n";
|
|
||||||
picode = &latch->back();
|
|
||||||
picode->invalidate();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ENDLESS_TYPE:
|
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
|
|
||||||
}
|
|
||||||
cCode.appendCode(ostr.str());
|
|
||||||
stats.numHLIcode += 1;
|
|
||||||
indLevel++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the code for this basic block */
|
/* Write the code for this basic block */
|
||||||
@ -211,18 +241,16 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for end of path */
|
/* Check for end of path */
|
||||||
_nodeType = nodeType;
|
if (isEndOfPath(_latchNode))
|
||||||
if (_nodeType == RETURN_NODE || _nodeType == TERMINATE_NODE ||
|
|
||||||
_nodeType == NOWHERE_NODE || (dfsLastNum == _latchNode))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check type of loop/node and process code */
|
/* Check type of loop/node and process code */
|
||||||
if (_loopType) /* there is a loop */
|
if ( loopType) /* there is a loop */
|
||||||
{
|
{
|
||||||
assert(latch);
|
assert(latch);
|
||||||
if (this != latch) /* loop is over several bbs */
|
if (this != latch) /* loop is over several bbs */
|
||||||
{
|
{
|
||||||
if (_loopType == WHILE_TYPE)
|
if (loopType == WHILE_TYPE)
|
||||||
{
|
{
|
||||||
succ = edges[THEN].BBptr;
|
succ = edges[THEN].BBptr;
|
||||||
if (succ->dfsLastNum == loopFollow)
|
if (succ->dfsLastNum == loopFollow)
|
||||||
@ -238,7 +266,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
|
|
||||||
/* Loop epilogue: generate the loop trailer */
|
/* Loop epilogue: generate the loop trailer */
|
||||||
indLevel--;
|
indLevel--;
|
||||||
if (_loopType == WHILE_TYPE)
|
if (loopType == WHILE_TYPE)
|
||||||
{
|
{
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
/* Check if there is need to repeat other statements involved
|
/* Check if there is need to repeat other statements involved
|
||||||
@ -250,9 +278,9 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
ostr <<indentStr(indLevel)<< "} /* end of while */\n";
|
ostr <<indentStr(indLevel)<< "} /* end of while */\n";
|
||||||
cCode.appendCode(ostr.str());
|
cCode.appendCode(ostr.str());
|
||||||
}
|
}
|
||||||
else if (_loopType == ENDLESS_TYPE)
|
else if (loopType == ENDLESS_TYPE)
|
||||||
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
|
cCode.appendCode( "%s} /* end of loop */\n",indentStr(indLevel));
|
||||||
else if (_loopType == REPEAT_TYPE)
|
else if (loopType == REPEAT_TYPE)
|
||||||
{
|
{
|
||||||
if (picode->hl()->opcode != HLI_JCOND)
|
if (picode->hl()->opcode != HLI_JCOND)
|
||||||
reportError (REPEAT_FAIL);
|
reportError (REPEAT_FAIL);
|
||||||
@ -275,7 +303,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
|
|
||||||
else /* no loop, process nodeType of the graph */
|
else /* no loop, process nodeType of the graph */
|
||||||
{
|
{
|
||||||
if (_nodeType == TWO_BRANCH) /* if-then[-else] */
|
if (nodeType == TWO_BRANCH) /* if-then[-else] */
|
||||||
{
|
{
|
||||||
stats.numHLIcode++;
|
stats.numHLIcode++;
|
||||||
indLevel++;
|
indLevel++;
|
||||||
@ -344,8 +372,11 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
else /* fall, call, 1w */
|
else /* fall, call, 1w */
|
||||||
{
|
{
|
||||||
succ = edges[0].BBptr; /* fall-through edge */
|
succ = edges[0].BBptr; /* fall-through edge */
|
||||||
|
assert(succ->size()>0);
|
||||||
if (succ->traversed != DFS_ALPHA)
|
if (succ->traversed != DFS_ALPHA)
|
||||||
|
{
|
||||||
succ->writeCode (indLevel, pProc,numLoc, _latchNode,_ifFollow);
|
succ->writeCode (indLevel, pProc,numLoc, _latchNode,_ifFollow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,7 +392,7 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
|
|||||||
|
|
||||||
/* Generate code for each hlicode that is not a HLI_JCOND */
|
/* Generate code for each hlicode that is not a HLI_JCOND */
|
||||||
|
|
||||||
for(ICODE &pHli : *this)
|
for(ICODE &pHli : instructions)
|
||||||
{
|
{
|
||||||
if ((pHli.type == HIGH_LEVEL) && ( pHli.valid() )) //TODO: use filtering range here.
|
if ((pHli.type == HIGH_LEVEL) && ( pHli.valid() )) //TODO: use filtering range here.
|
||||||
{
|
{
|
||||||
@ -379,33 +410,34 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
|
|||||||
|
|
||||||
iICODE BB::begin()
|
iICODE BB::begin()
|
||||||
{
|
{
|
||||||
return range_start;
|
return instructions.begin();//range_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
iICODE BB::end() const
|
iICODE BB::end() const
|
||||||
{
|
{
|
||||||
return range_end;
|
return instructions.end();//range_end
|
||||||
}
|
}
|
||||||
ICODE &BB::back()
|
ICODE &BB::back()
|
||||||
{
|
{
|
||||||
return *rbegin();
|
return instructions.back();//*rbegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t BB::size()
|
size_t BB::size()
|
||||||
{
|
{
|
||||||
return distance(range_start,range_end);
|
|
||||||
|
return distance(instructions.begin(),instructions.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
ICODE &BB::front()
|
ICODE &BB::front()
|
||||||
{
|
{
|
||||||
return *begin();
|
return instructions.front();//*begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
riICODE BB::rbegin()
|
riICODE BB::rbegin()
|
||||||
{
|
{
|
||||||
return riICODE(end());
|
return riICODE( instructions.end() );
|
||||||
}
|
}
|
||||||
riICODE BB::rend()
|
riICODE BB::rend()
|
||||||
{
|
{
|
||||||
return riICODE(begin());
|
return riICODE( instructions.begin() );
|
||||||
}
|
}
|
||||||
|
|||||||
@ -823,7 +823,7 @@ void COND_EXPR::changeBoolOp (condOp newOp)
|
|||||||
|
|
||||||
/* Inserts the expression exp into the tree at the location specified by the
|
/* Inserts the expression exp into the tree at the location specified by the
|
||||||
* register regi */
|
* register regi */
|
||||||
bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,LOCAL_ID *locsym)
|
bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (tree == NULL)
|
if (tree == NULL)
|
||||||
@ -836,7 +836,7 @@ bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
COND_EXPR *COND_EXPR::insertSubTreeReg (COND_EXPR *_expr, eReg regi,LOCAL_ID *locsym)
|
COND_EXPR *COND_EXPR::insertSubTreeReg (COND_EXPR *_expr, eReg regi,const LOCAL_ID *locsym)
|
||||||
{
|
{
|
||||||
|
|
||||||
eReg treeReg;
|
eReg treeReg;
|
||||||
|
|||||||
@ -2,14 +2,16 @@
|
|||||||
* Description : Performs control flow analysis on the CFG
|
* Description : Performs control flow analysis on the CFG
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
#include <boost/range/algorithm.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "dcc.h"
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
|
|
||||||
//typedef struct list {
|
//typedef struct list {
|
||||||
// int nodeIdx;
|
// int nodeIdx;
|
||||||
// struct list *next;
|
// struct list *next;
|
||||||
@ -577,6 +579,7 @@ bool Function::Case_X_or_Y(BB* pbb, BB* thenBB, BB* elseBB)
|
|||||||
hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR));
|
hl1.expr(COND_EXPR::boolOp (hl1.expr(), hl2.expr(), DBL_OR));
|
||||||
|
|
||||||
/* Replace in-edge to obb from t to pbb */
|
/* Replace in-edge to obb from t to pbb */
|
||||||
|
|
||||||
auto iter=find(obb->inEdges.begin(),obb->inEdges.end(),thenBB);
|
auto iter=find(obb->inEdges.begin(),obb->inEdges.end(),thenBB);
|
||||||
if(iter!=obb->inEdges.end())
|
if(iter!=obb->inEdges.end())
|
||||||
*iter = pbb;
|
*iter = pbb;
|
||||||
|
|||||||
563
src/dataflow.cpp
563
src/dataflow.cpp
@ -9,6 +9,7 @@
|
|||||||
#include <boost/range.hpp>
|
#include <boost/range.hpp>
|
||||||
#include <boost/range/adaptors.hpp>
|
#include <boost/range/adaptors.hpp>
|
||||||
#include <boost/range/algorithm.hpp>
|
#include <boost/range/algorithm.hpp>
|
||||||
|
#include <boost/assign.hpp>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@ -24,6 +25,13 @@ struct ExpStack
|
|||||||
COND_EXPR * pop();
|
COND_EXPR * pop();
|
||||||
int numElem();
|
int numElem();
|
||||||
boolT empty();
|
boolT empty();
|
||||||
|
void processExpPush(int &numHlIcodes, iICODE picode)
|
||||||
|
{
|
||||||
|
push(picode->hl()->expr());
|
||||||
|
picode->invalidate();
|
||||||
|
numHlIcodes--;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Expression stack functions
|
* Expression stack functions
|
||||||
@ -266,6 +274,8 @@ void Function::genLiveKtes ()
|
|||||||
* Propagates register usage information to the procedure call. */
|
* Propagates register usage information to the procedure call. */
|
||||||
void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
||||||
{
|
{
|
||||||
|
using namespace boost::adaptors;
|
||||||
|
using namespace boost::assign;
|
||||||
BB * pbb=0; /* pointer to current basic block */
|
BB * pbb=0; /* pointer to current basic block */
|
||||||
Function * pcallee; /* invoked subroutine */
|
Function * pcallee; /* invoked subroutine */
|
||||||
//ICODE *ticode /* icode that invokes a subroutine */
|
//ICODE *ticode /* icode that invokes a subroutine */
|
||||||
@ -282,14 +292,10 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
|||||||
{
|
{
|
||||||
/* Process nodes in reverse postorder order */
|
/* Process nodes in reverse postorder order */
|
||||||
change = false;
|
change = false;
|
||||||
//for (i = numBBs; i > 0; i--)
|
auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
|
||||||
//boost::RandomAccessContainerConcept;
|
for( BB * _pbb : valid_reversed_bbs)
|
||||||
|
|
||||||
for(auto iBB=m_dfsLast.rbegin(); iBB!=m_dfsLast.rend(); ++iBB)
|
|
||||||
{
|
{
|
||||||
pbb = *iBB;//m_dfsLast[i-1];
|
pbb = _pbb;//*iBB;//m_dfsLast[i-1];
|
||||||
if (pbb->flg & INVALID_BB) /* Do not process invalid BBs */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Get current liveIn() and liveOut() sets */
|
/* Get current liveIn() and liveOut() sets */
|
||||||
prevLiveIn = pbb->liveIn;
|
prevLiveIn = pbb->liveIn;
|
||||||
@ -307,7 +313,6 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
|||||||
auto picode = pbb->rbegin(); /* icode of function return */
|
auto picode = pbb->rbegin(); /* icode of function return */
|
||||||
if (picode->hl()->opcode == HLI_RET)
|
if (picode->hl()->opcode == HLI_RET)
|
||||||
{
|
{
|
||||||
//pbb->back().loc_ip
|
|
||||||
picode->hl()->expr(COND_EXPR::idID (&retVal, &localId, (++pbb->rbegin()).base()));
|
picode->hl()->expr(COND_EXPR::idID (&retVal, &localId, (++pbb->rbegin()).base()));
|
||||||
picode->du.use = in_liveOut;
|
picode->du.use = in_liveOut;
|
||||||
}
|
}
|
||||||
@ -393,6 +398,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
|||||||
|
|
||||||
void BB::genDU1()
|
void BB::genDU1()
|
||||||
{
|
{
|
||||||
|
using namespace boost::adaptors;
|
||||||
eReg regi; /* Register that was defined */
|
eReg regi; /* Register that was defined */
|
||||||
int k, defRegIdx, useIdx;
|
int k, defRegIdx, useIdx;
|
||||||
iICODE picode, ticode,lastInst;
|
iICODE picode, ticode,lastInst;
|
||||||
@ -404,10 +410,13 @@ void BB::genDU1()
|
|||||||
*/
|
*/
|
||||||
assert(0!=Parent);
|
assert(0!=Parent);
|
||||||
lastInst = this->end();
|
lastInst = this->end();
|
||||||
for (picode = this->begin(); picode != lastInst; picode++)
|
ICODE::TypeFilter<HIGH_LEVEL> zq;
|
||||||
|
auto all_high_levels = instructions | filtered(zq);
|
||||||
|
printf("\n");
|
||||||
|
for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode)
|
||||||
{
|
{
|
||||||
if (picode->type != HIGH_LEVEL)
|
// if (picode->type != HIGH_LEVEL)
|
||||||
continue;
|
// continue;
|
||||||
regi = rUNDEF;
|
regi = rUNDEF;
|
||||||
defRegIdx = 0;
|
defRegIdx = 0;
|
||||||
// foreach defined register
|
// foreach defined register
|
||||||
@ -428,10 +437,10 @@ void BB::genDU1()
|
|||||||
continue;
|
continue;
|
||||||
if ((regi == rSI) && (flg & SI_REGVAR))
|
if ((regi == rSI) && (flg & SI_REGVAR))
|
||||||
continue;
|
continue;
|
||||||
if (distance(picode,lastInst)>1) /* several instructions */
|
if (distance(picode,all_high_levels.end())>1) /* several instructions */
|
||||||
{
|
{
|
||||||
useIdx = 0;
|
useIdx = 0;
|
||||||
for (auto ricode = ++iICODE(picode); ricode != lastInst; ricode++)
|
for (auto ricode = ++iICODE(picode.base()); ricode != lastInst; ricode++)
|
||||||
{
|
{
|
||||||
ticode=ricode;
|
ticode=ricode;
|
||||||
if (ricode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
|
if (ricode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
|
||||||
@ -503,9 +512,9 @@ void BB::genDU1()
|
|||||||
|
|
||||||
/* Backpatch any uses of this instruction, within
|
/* Backpatch any uses of this instruction, within
|
||||||
* the same BB, if the instruction was invalidated */
|
* the same BB, if the instruction was invalidated */
|
||||||
for (auto back_patch_at = riICODE(picode); back_patch_at != rend(); back_patch_at++)
|
for (auto back_patch_at = riICODE(picode.base()); back_patch_at != rend(); back_patch_at++)
|
||||||
{
|
{
|
||||||
back_patch_at->du1.remove(0,picode);
|
back_patch_at->du1.remove(0,picode.base());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* liveOut */
|
else /* liveOut */
|
||||||
@ -536,18 +545,15 @@ void Function::genDU1 ()
|
|||||||
|
|
||||||
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
|
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
|
||||||
* of picode. */
|
* of picode. */
|
||||||
static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode,
|
void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
|
||||||
iICODE ticode, LOCAL_ID *locsym, int &numHlIcodes)
|
|
||||||
{
|
{
|
||||||
boolT res;
|
bool res;
|
||||||
|
|
||||||
if (rhs == NULL) /* In case expression popped is NULL */
|
if (rhs == NULL) /* In case expression popped is NULL */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Insert on rhs of ticode, if possible */
|
/* Insert on rhs of ticode, if possible */
|
||||||
res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs,
|
res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this);
|
||||||
locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi,
|
|
||||||
locsym);
|
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
@ -556,9 +562,7 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Try to insert it on lhs of ticode*/
|
/* Try to insert it on lhs of ticode*/
|
||||||
res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs,
|
res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this);
|
||||||
locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi,
|
|
||||||
locsym);
|
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
@ -599,7 +603,7 @@ static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE
|
|||||||
|
|
||||||
/* Returns whether the elements of the expression rhs are all x-clear from
|
/* Returns whether the elements of the expression rhs are all x-clear from
|
||||||
* instruction f up to instruction t. */
|
* instruction f up to instruction t. */
|
||||||
bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, Function * pproc)
|
bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID & locId)
|
||||||
{
|
{
|
||||||
iICODE i;
|
iICODE i;
|
||||||
boolT res;
|
boolT res;
|
||||||
@ -610,7 +614,7 @@ bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, Function * pproc)
|
|||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
if (expr.ident.idType == REGISTER)
|
if (expr.ident.idType == REGISTER)
|
||||||
{
|
{
|
||||||
regi= pproc->localId.id_arr[expr.ident.idNode.regiIdx].id.regi;
|
regi= locId.id_arr[expr.ident.idNode.regiIdx].id.regi;
|
||||||
for (i = ++iICODE(f); (i != lastBBinst) && (i!=t); i++)
|
for (i = ++iICODE(f); (i != lastBBinst) && (i!=t); i++)
|
||||||
if ((i->type == HIGH_LEVEL) && ( i->valid() ))
|
if ((i->type == HIGH_LEVEL) && ( i->valid() ))
|
||||||
{
|
{
|
||||||
@ -631,38 +635,38 @@ bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, Function * pproc)
|
|||||||
case BOOLEAN_OP:
|
case BOOLEAN_OP:
|
||||||
if(0==rhs())
|
if(0==rhs())
|
||||||
return false;
|
return false;
|
||||||
res = rhs()->xClear ( f, t, lastBBinst, pproc);
|
res = rhs()->xClear ( f, t, lastBBinst, locId);
|
||||||
if (res == false)
|
if (res == false)
|
||||||
return false;
|
return false;
|
||||||
if(0==lhs())
|
if(0==lhs())
|
||||||
return false;
|
return false;
|
||||||
return lhs()->xClear ( f, t, lastBBinst, pproc);
|
return lhs()->xClear ( f, t, lastBBinst, locId);
|
||||||
|
|
||||||
case NEGATION:
|
case NEGATION:
|
||||||
case ADDRESSOF:
|
case ADDRESSOF:
|
||||||
case DEREFERENCE:
|
case DEREFERENCE:
|
||||||
if(0==expr.unaryExp)
|
if(0==expr.unaryExp)
|
||||||
return false;
|
return false;
|
||||||
return expr.unaryExp->xClear ( f, t, lastBBinst, pproc);
|
return expr.unaryExp->xClear ( f, t, lastBBinst, locId);
|
||||||
} /* eos */
|
} /* eos */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool UnaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc)
|
bool UnaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locs)
|
||||||
{
|
{
|
||||||
if(0==unaryExp)
|
if(0==unaryExp)
|
||||||
return false;
|
return false;
|
||||||
return unaryExp->xClear ( f, t, lastBBinst, pproc);
|
return unaryExp->xClear ( f, t, lastBBinst, locs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BinaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, Function *pproc)
|
bool BinaryOperator::xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locs)
|
||||||
{
|
{
|
||||||
if(0==m_rhs)
|
if(0==m_rhs)
|
||||||
return false;
|
return false;
|
||||||
if ( ! m_rhs->xClear (f, t, lastBBinst, pproc) )
|
if ( ! m_rhs->xClear (f, t, lastBBinst, locs) )
|
||||||
return false;
|
return false;
|
||||||
if(0==m_lhs)
|
if(0==m_lhs)
|
||||||
return false;
|
return false;
|
||||||
return m_lhs->xClear (f, t, lastBBinst, pproc);
|
return m_lhs->xClear (f, t, lastBBinst, locs);
|
||||||
}
|
}
|
||||||
/* Checks the type of the formal argument as against to the actual argument,
|
/* Checks the type of the formal argument as against to the actual argument,
|
||||||
* whenever possible, and then places the actual argument on the procedure's
|
* whenever possible, and then places the actual argument on the procedure's
|
||||||
@ -712,37 +716,39 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, int num
|
|||||||
/** Eliminates extraneous intermediate icode instructions when finding
|
/** Eliminates extraneous intermediate icode instructions when finding
|
||||||
* expressions. Generates new hlIcodes in the form of expression trees.
|
* expressions. Generates new hlIcodes in the form of expression trees.
|
||||||
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
|
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
|
||||||
void Function::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong)
|
void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const
|
||||||
{
|
{
|
||||||
boolT res;
|
boolT res;
|
||||||
switch (ticode->hl()->opcode) {
|
HLTYPE &p_hl(*picode->hl());
|
||||||
|
HLTYPE &t_hl(*ticode->hl());
|
||||||
|
switch (t_hl.opcode)
|
||||||
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
if(isLong)
|
if(isLong)
|
||||||
{
|
{
|
||||||
forwardSubsLong (picode->hl()->asgn.lhs->expr.ident.idNode.longIdx,
|
forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx,
|
||||||
picode->hl()->asgn.rhs, picode,ticode,
|
p_hl.asgn.rhs, picode,ticode,
|
||||||
&numHlIcodes);
|
&numHlIcodes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
forwardSubs (picode->hl()->asgn.lhs, picode->hl()->asgn.rhs,
|
this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes);
|
||||||
picode, ticode, &localId, numHlIcodes);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
||||||
if(isLong)
|
if(isLong)
|
||||||
{
|
{
|
||||||
res = COND_EXPR::insertSubTreeLongReg (
|
res = COND_EXPR::insertSubTreeLongReg (
|
||||||
picode->hl()->asgn.rhs,
|
p_hl.asgn.rhs,
|
||||||
&ticode->hl()->exp.v,
|
&t_hl.exp.v,
|
||||||
picode->hl()->asgn.lhs->expr.ident.idNode.longIdx);
|
p_hl.asgn.lhs->expr.ident.idNode.longIdx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = COND_EXPR::insertSubTreeReg (
|
res = COND_EXPR::insertSubTreeReg (
|
||||||
ticode->hl()->exp.v,
|
t_hl.exp.v,
|
||||||
picode->hl()->asgn.rhs,
|
p_hl.asgn.rhs,
|
||||||
localId.id_arr[picode->hl()->asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
|
id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
|
||||||
&localId);
|
this);
|
||||||
}
|
}
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
@ -821,274 +827,282 @@ void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Function::findExps()
|
|
||||||
|
int BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
||||||
{
|
{
|
||||||
int i, numHlIcodes;
|
bool res;
|
||||||
iICODE
|
|
||||||
picode, // Current icode */
|
ID *_retVal; // function return value
|
||||||
ticode; // Target icode */
|
|
||||||
BB * pbb; // Current and next basic block */
|
|
||||||
boolT res;
|
|
||||||
COND_EXPR *_exp, // expression pointer - for HLI_POP and HLI_CALL */
|
COND_EXPR *_exp, // expression pointer - for HLI_POP and HLI_CALL */
|
||||||
*lhs; // exp ptr for return value of a HLI_CALL */
|
*lhs; // exp ptr for return value of a HLI_CALL */
|
||||||
//STKFRAME * args; // pointer to arguments - for HLI_CALL */
|
iICODE ticode; // Target icode */
|
||||||
uint8_t regi; // register(s) to be forward substituted */
|
HLTYPE *ti_hl=0;
|
||||||
ID *_retVal; // function return value
|
uint8_t regi;
|
||||||
|
numHlIcodes = 0;
|
||||||
/* Initialize expression stack */
|
// register(s) to be forward substituted */
|
||||||
g_exp_stk.init();
|
for (iICODE picode = begin(); picode != end(); picode++)
|
||||||
|
|
||||||
_exp = 0;
|
|
||||||
/* Traverse tree in dfsLast order */
|
|
||||||
for (i = 0; i < numBBs; i++)
|
|
||||||
{
|
{
|
||||||
/* Process one BB */
|
if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() ))
|
||||||
pbb = m_dfsLast[i];
|
|
||||||
if (pbb->flg & INVALID_BB)
|
|
||||||
continue;
|
continue;
|
||||||
numHlIcodes = 0;
|
HLTYPE &_icHl(*picode->hl());
|
||||||
for (picode = pbb->begin(); picode != pbb->end(); picode++)
|
numHlIcodes++;
|
||||||
|
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
|
||||||
{
|
{
|
||||||
if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() ))
|
/* Check for only one use of this register. If this is
|
||||||
continue;
|
* the last definition of the register in this BB, check
|
||||||
numHlIcodes++;
|
* that it is not liveOut from this basic block */
|
||||||
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
|
if (picode->du1.numUses(0)==1)
|
||||||
{
|
{
|
||||||
/* Check for only one use of this register. If this is
|
/* Check that this register is not liveOut, if it
|
||||||
* the last definition of the register in this BB, check
|
* is the last definition of the register */
|
||||||
* that it is not liveOut from this basic block */
|
regi = picode->du1.regi[0];
|
||||||
if (picode->du1.numUses(0)==1)
|
|
||||||
|
/* Check if we can forward substitute this register */
|
||||||
|
switch (_icHl.opcode)
|
||||||
{
|
{
|
||||||
/* Check that this register is not liveOut, if it
|
case HLI_ASSIGN:
|
||||||
* is the last definition of the register */
|
/* Replace rhs of current icode into target
|
||||||
regi = picode->du1.regi[0];
|
|
||||||
|
|
||||||
/* Check if we can forward substitute this register */
|
|
||||||
switch (picode->hl()->opcode)
|
|
||||||
{
|
|
||||||
case HLI_ASSIGN:
|
|
||||||
/* Replace rhs of current icode into target
|
|
||||||
* icode expression */
|
* icode expression */
|
||||||
|
|
||||||
|
ticode = picode->du1.idx[0].uses.front();
|
||||||
|
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||||
|
((ticode->hl()->opcode != HLI_CALL) &&
|
||||||
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_icHl.asgn.rhs->xClear (picode,
|
||||||
|
picode->du1.idx[0].uses[0],
|
||||||
|
end(), locals))
|
||||||
|
{
|
||||||
|
locals.processTargetIcode(picode, numHlIcodes, ticode,false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLI_POP:
|
||||||
|
ticode = picode->du1.idx[0].uses.front();
|
||||||
|
ti_hl = ticode->hl();
|
||||||
|
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||||
|
((ti_hl->opcode != HLI_CALL) &&
|
||||||
|
(ti_hl->opcode != HLI_RET)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_exp = g_exp_stk.pop(); /* pop last exp pushed */
|
||||||
|
switch (ticode->hl()->opcode) {
|
||||||
|
case HLI_ASSIGN:
|
||||||
|
locals.forwardSubs(_icHl.expr(), _exp, picode, ticode, numHlIcodes);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
||||||
|
res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v,
|
||||||
|
_exp,
|
||||||
|
locals.id_arr[_icHl.expr()->expr.ident.idNode.regiIdx].id.regi,
|
||||||
|
&locals);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
picode->invalidate();
|
||||||
|
numHlIcodes--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/****case HLI_CALL: /* register arguments
|
||||||
|
newRegArg (pProc, picode, ticode);
|
||||||
|
picode->invalidate();
|
||||||
|
numHlIcodes--;
|
||||||
|
break; */
|
||||||
|
} /* eos */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLI_CALL:
|
||||||
|
ticode = picode->du1.idx[0].uses.front();
|
||||||
|
ti_hl = ticode->hl();
|
||||||
|
_retVal = &_icHl.call.proc->retVal;
|
||||||
|
switch (ti_hl->opcode)
|
||||||
|
{
|
||||||
|
case HLI_ASSIGN:
|
||||||
|
assert(ti_hl->asgn.rhs);
|
||||||
|
_exp = _icHl.call.toId();
|
||||||
|
res = COND_EXPR::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals);
|
||||||
|
if (! res)
|
||||||
|
COND_EXPR::insertSubTreeReg (ti_hl->asgn.lhs, _exp,_retVal->id.regi, &locals);
|
||||||
|
//TODO: HERE missing: 2 regs
|
||||||
|
picode->invalidate();
|
||||||
|
numHlIcodes--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLI_PUSH: case HLI_RET:
|
||||||
|
ti_hl->expr( _icHl.call.toId() );
|
||||||
|
picode->invalidate();
|
||||||
|
numHlIcodes--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLI_JCOND:
|
||||||
|
_exp = _icHl.call.toId();
|
||||||
|
res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
|
||||||
|
if (res) /* was substituted */
|
||||||
|
{
|
||||||
|
picode->invalidate();
|
||||||
|
numHlIcodes--;
|
||||||
|
}
|
||||||
|
else /* cannot substitute function */
|
||||||
|
{
|
||||||
|
//picode->loc_ip
|
||||||
|
lhs = COND_EXPR::idID(_retVal,&locals,picode);
|
||||||
|
picode->setAsgn(lhs, _exp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} /* eos */
|
||||||
|
break;
|
||||||
|
} /* eos */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (picode->du1.numRegsDef == 2) /* long regs */
|
||||||
|
{
|
||||||
|
/* Check for only one use of these registers */
|
||||||
|
if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
|
||||||
|
{
|
||||||
|
regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this
|
||||||
|
|
||||||
|
switch (_icHl.opcode)
|
||||||
|
{
|
||||||
|
case HLI_ASSIGN:
|
||||||
|
/* Replace rhs of current icode into target
|
||||||
|
* icode expression */
|
||||||
|
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
||||||
|
{
|
||||||
|
ticode = picode->du1.idx[0].uses.front();
|
||||||
|
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||||
|
((ticode->hl()->opcode != HLI_CALL) &&
|
||||||
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
|
continue;
|
||||||
|
locals.processTargetIcode(picode, numHlIcodes, ticode,true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLI_POP:
|
||||||
|
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
||||||
|
{
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
ticode = picode->du1.idx[0].uses.front();
|
||||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
||||||
((ticode->hl()->opcode != HLI_CALL) &&
|
((ticode->hl()->opcode != HLI_CALL) &&
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
(ticode->hl()->opcode != HLI_RET)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (picode->hl()->asgn.rhs->xClear (picode,
|
_exp = g_exp_stk.pop(); /* pop last exp pushed */
|
||||||
picode->du1.idx[0].uses[0], pbb->end(), this))
|
|
||||||
{
|
|
||||||
processTargetIcode(picode, numHlIcodes, ticode,false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLI_POP:
|
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
|
||||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
|
||||||
((ticode->hl()->opcode != HLI_CALL) &&
|
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
_exp = g_exp_stk.pop(); /* pop last exp pushed */
|
|
||||||
switch (ticode->hl()->opcode) {
|
switch (ticode->hl()->opcode) {
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
forwardSubs (picode->hl()->expr(), _exp,
|
forwardSubsLong (_icHl.expr()->expr.ident.idNode.longIdx,
|
||||||
picode, ticode, &localId,
|
_exp, picode, ticode, &numHlIcodes);
|
||||||
numHlIcodes);
|
|
||||||
break;
|
break;
|
||||||
|
case HLI_JCOND: case HLI_PUSH:
|
||||||
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
res = COND_EXPR::insertSubTreeLongReg (_exp,
|
||||||
res = COND_EXPR::insertSubTreeReg (ticode->hl()->exp.v,
|
&ticode->hl()->exp.v,
|
||||||
_exp,
|
_icHl.asgn.lhs->expr.ident.idNode.longIdx);
|
||||||
localId.id_arr[picode->hl()->expr()->expr.ident.idNode.regiIdx].id.regi,
|
|
||||||
&localId);
|
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case HLI_CALL: /*** missing ***/
|
||||||
/****case HLI_CALL: /* register arguments
|
|
||||||
newRegArg (pProc, picode, ticode);
|
|
||||||
picode->invalidate();
|
|
||||||
numHlIcodes--;
|
|
||||||
break; */
|
|
||||||
} /* eos */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLI_CALL:
|
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
|
||||||
HLTYPE *ti_hl(ticode->hl());
|
|
||||||
_retVal = &picode->hl()->call.proc->retVal;
|
|
||||||
switch (ti_hl->opcode) {
|
|
||||||
case HLI_ASSIGN:
|
|
||||||
assert(ti_hl->asgn.rhs);
|
|
||||||
_exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args);
|
|
||||||
res = COND_EXPR::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &localId);
|
|
||||||
if (! res)
|
|
||||||
COND_EXPR::insertSubTreeReg (ti_hl->asgn.lhs, _exp,_retVal->id.regi, &localId);
|
|
||||||
//TODO: HERE missing: 2 regs
|
|
||||||
picode->invalidate();
|
|
||||||
numHlIcodes--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLI_PUSH: case HLI_RET:
|
|
||||||
ti_hl->expr( COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args) );
|
|
||||||
picode->invalidate();
|
|
||||||
numHlIcodes--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLI_JCOND:
|
|
||||||
_exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args);
|
|
||||||
res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &localId);
|
|
||||||
if (res) /* was substituted */
|
|
||||||
{
|
|
||||||
picode->invalidate();
|
|
||||||
numHlIcodes--;
|
|
||||||
}
|
|
||||||
else /* cannot substitute function */
|
|
||||||
{
|
|
||||||
//picode->loc_ip
|
|
||||||
lhs = COND_EXPR::idID(_retVal,&localId,picode);
|
|
||||||
picode->setAsgn(lhs, _exp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
} /* eos */
|
} /* eos */
|
||||||
break;
|
}
|
||||||
} /* eos */
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (picode->du1.numRegsDef == 2) /* long regs */
|
case HLI_CALL: /* check for function return */
|
||||||
{
|
ticode = picode->du1.idx[0].uses.front();
|
||||||
/* Check for only one use of these registers */
|
switch (ticode->hl()->opcode)
|
||||||
if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
|
{
|
||||||
{
|
case HLI_ASSIGN:
|
||||||
regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this
|
_exp = _icHl.call.toId();
|
||||||
|
ticode->hl()->asgn.lhs =
|
||||||
|
COND_EXPR::idLong(&locals, DST, ticode,HIGH_FIRST, picode, eDEF, ++iICODE(ticode));
|
||||||
|
ticode->hl()->asgn.rhs = _exp;
|
||||||
|
picode->invalidate();
|
||||||
|
numHlIcodes--;
|
||||||
|
break;
|
||||||
|
|
||||||
switch (picode->hl()->opcode) {
|
case HLI_PUSH: case HLI_RET:
|
||||||
case HLI_ASSIGN:
|
ticode->hl()->expr( _icHl.call.toId() );
|
||||||
/* Replace rhs of current icode into target
|
picode->invalidate();
|
||||||
* icode expression */
|
numHlIcodes--;
|
||||||
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
break;
|
||||||
{
|
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
|
||||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
|
||||||
((ticode->hl()->opcode != HLI_CALL) &&
|
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
|
||||||
continue;
|
|
||||||
processTargetIcode(picode, numHlIcodes, ticode,true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLI_POP:
|
case HLI_JCOND:
|
||||||
if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
|
_exp = _icHl.call.toId();
|
||||||
{
|
_retVal = &picode->hl()->call.proc->retVal;
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
res = COND_EXPR::insertSubTreeLongReg (_exp,
|
||||||
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
|
&ticode->hl()->exp.v,
|
||||||
((ticode->hl()->opcode != HLI_CALL) &&
|
locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
|
||||||
(ticode->hl()->opcode != HLI_RET)))
|
_retVal->id.longId.l, picode));
|
||||||
continue;
|
if (res) /* was substituted */
|
||||||
|
{
|
||||||
_exp = g_exp_stk.pop(); /* pop last exp pushed */
|
|
||||||
switch (ticode->hl()->opcode) {
|
|
||||||
case HLI_ASSIGN:
|
|
||||||
forwardSubsLong (picode->hl()->expr()->expr.ident.idNode.longIdx,
|
|
||||||
_exp, picode, ticode, &numHlIcodes);
|
|
||||||
break;
|
|
||||||
case HLI_JCOND: case HLI_PUSH:
|
|
||||||
res = COND_EXPR::insertSubTreeLongReg (_exp,
|
|
||||||
&ticode->hl()->exp.v,
|
|
||||||
picode->hl()->asgn.lhs->expr.ident.idNode.longIdx);
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
picode->invalidate();
|
|
||||||
numHlIcodes--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HLI_CALL: /*** missing ***/
|
|
||||||
break;
|
|
||||||
} /* eos */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HLI_CALL: /* check for function return */
|
|
||||||
ticode = picode->du1.idx[0].uses.front();
|
|
||||||
switch (ticode->hl()->opcode)
|
|
||||||
{
|
|
||||||
case HLI_ASSIGN:
|
|
||||||
_exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args);
|
|
||||||
ticode->hl()->asgn.lhs =
|
|
||||||
COND_EXPR::idLong(&localId, DST, ticode,HIGH_FIRST, picode, eDEF, ++iICODE(ticode));
|
|
||||||
ticode->hl()->asgn.rhs = _exp;
|
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
}
|
||||||
|
else /* cannot substitute function */
|
||||||
case HLI_PUSH: case HLI_RET:
|
{
|
||||||
ticode->hl()->expr( COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args) );
|
lhs = locals.createId(_retVal,picode);
|
||||||
picode->invalidate();
|
picode->setAsgn(lhs, _exp);
|
||||||
numHlIcodes--;
|
}
|
||||||
break;
|
break;
|
||||||
|
} /* eos */
|
||||||
case HLI_JCOND:
|
} /* eos */
|
||||||
_exp = COND_EXPR::idFunc ( picode->hl()->call.proc, picode->hl()->call.args);
|
|
||||||
_retVal = &picode->hl()->call.proc->retVal;
|
|
||||||
res = COND_EXPR::insertSubTreeLongReg (_exp,
|
|
||||||
&ticode->hl()->exp.v,
|
|
||||||
localId.newLongReg ( _retVal->type, _retVal->id.longId.h,
|
|
||||||
_retVal->id.longId.l, picode));
|
|
||||||
if (res) /* was substituted */
|
|
||||||
{
|
|
||||||
picode->invalidate();
|
|
||||||
numHlIcodes--;
|
|
||||||
}
|
|
||||||
else /* cannot substitute function */
|
|
||||||
{
|
|
||||||
lhs = COND_EXPR::idID(_retVal,&localId,picode/*picode->loc_ip*/);
|
|
||||||
picode->setAsgn(lhs, _exp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} /* eos */
|
|
||||||
} /* eos */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/* HLI_PUSH doesn't define any registers, only uses registers.
|
||||||
|
* Push the associated expression to the register on the local
|
||||||
|
* expression stack */
|
||||||
|
else if (_icHl.opcode == HLI_PUSH)
|
||||||
|
{
|
||||||
|
g_exp_stk.processExpPush(numHlIcodes, picode);
|
||||||
|
}
|
||||||
|
else if(picode->du1.numRegsDef!=0)
|
||||||
|
printf("Num def %d\n",picode->du1.numRegsDef);
|
||||||
|
|
||||||
/* HLI_PUSH doesn't define any registers, only uses registers.
|
/* For HLI_CALL instructions that use arguments from the stack,
|
||||||
* Push the associated expression to the register on the local
|
* pop them from the expression stack and place them on the
|
||||||
* expression stack */
|
* procedure's argument list */
|
||||||
else if (picode->hl()->opcode == HLI_PUSH)
|
if(_icHl.opcode == HLI_CALL)
|
||||||
|
{
|
||||||
|
if ( not _icHl.call.proc->hasRegArgs())
|
||||||
{
|
{
|
||||||
g_exp_stk.push(picode->hl()->expr());
|
fnc->processHliCall(_exp, picode);
|
||||||
picode->invalidate();
|
|
||||||
numHlIcodes--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For HLI_CALL instructions that use arguments from the stack,
|
|
||||||
* pop them from the expression stack and place them on the
|
|
||||||
* procedure's argument list */
|
|
||||||
|
|
||||||
if ((picode->hl()->opcode == HLI_CALL) && ! (picode->hl()->call.proc->flg & REG_ARGS))
|
|
||||||
{
|
|
||||||
processHliCall(_exp, picode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we could not substitute the result of a function,
|
/* If we could not substitute the result of a function,
|
||||||
* assign it to the corresponding registers */
|
* assign it to the corresponding registers */
|
||||||
if ((picode->hl()->opcode == HLI_CALL) &&
|
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0))
|
||||||
((picode->hl()->call.proc->flg & PROC_ISLIB) !=
|
|
||||||
PROC_ISLIB) && (not picode->du1.used(0)) &&
|
|
||||||
(picode->du1.numRegsDef > 0))
|
|
||||||
{
|
{
|
||||||
_exp = COND_EXPR::idFunc (picode->hl()->call.proc, picode->hl()->call.args);
|
_exp = COND_EXPR::idFunc (_icHl.call.proc, _icHl.call.args);
|
||||||
lhs = COND_EXPR::idID (&picode->hl()->call.proc->retVal, &localId, picode);
|
lhs = COND_EXPR::idID (&_icHl.call.proc->retVal, &locals, picode);
|
||||||
picode->setAsgn(lhs, _exp);
|
picode->setAsgn(lhs, _exp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/* Store number of high-level icodes in current basic block */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Function::findExps()
|
||||||
|
{
|
||||||
|
//int i, numHlIcodes;
|
||||||
|
//STKFRAME * args; // pointer to arguments - for HLI_CALL */
|
||||||
|
|
||||||
|
/* Initialize expression stack */
|
||||||
|
g_exp_stk.init();
|
||||||
|
|
||||||
|
/* Traverse tree in dfsLast order */
|
||||||
|
// for (i = 0; i < numBBs; i++)
|
||||||
|
for(BB *pbb : m_dfsLast)
|
||||||
|
{
|
||||||
|
/* Process one BB */
|
||||||
|
// pbb = m_dfsLast[i];
|
||||||
|
if (not pbb->valid())
|
||||||
|
continue;
|
||||||
|
pbb->findBBExps( this->localId, this);
|
||||||
|
|
||||||
/* Store number of high-level icodes in current basic block */
|
|
||||||
pbb->numHlIcodes = numHlIcodes;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1126,25 +1140,21 @@ void Function::dataFlow(std::bitset<32> &_liveOut)
|
|||||||
if(isAL && isAH)
|
if(isAL && isAH)
|
||||||
{
|
{
|
||||||
isAx = true;
|
isAx = true;
|
||||||
printf("**************************************************************************** dataFlow Join discovered Ax\n");
|
|
||||||
isAH=isAL=false;
|
isAH=isAL=false;
|
||||||
}
|
}
|
||||||
if(isDL && isDH)
|
if(isDL && isDH)
|
||||||
{
|
{
|
||||||
isDx = true;
|
isDx = true;
|
||||||
printf("**************************************************************************** dataFlow Join discovered Dx\n");
|
|
||||||
isDH=isDL=false;
|
isDH=isDL=false;
|
||||||
}
|
}
|
||||||
if(isBL && isBH)
|
if(isBL && isBH)
|
||||||
{
|
{
|
||||||
isBx = true;
|
isBx = true;
|
||||||
printf("**************************************************************************** dataFlow Join discovered Dx\n");
|
|
||||||
isBH=isBL=false;
|
isBH=isBL=false;
|
||||||
}
|
}
|
||||||
if(isCL && isCH)
|
if(isCL && isCH)
|
||||||
{
|
{
|
||||||
isCx = true;
|
isCx = true;
|
||||||
printf("**************************************************************************** dataFlow Join discovered Dx\n");
|
|
||||||
isCH=isCL=false;
|
isCH=isCL=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1173,7 +1183,6 @@ void Function::dataFlow(std::bitset<32> &_liveOut)
|
|||||||
}
|
}
|
||||||
else if(isAL||isBL||isCL||isDL)
|
else if(isAL||isBL||isCL||isDL)
|
||||||
{
|
{
|
||||||
printf("**************************************************************************** AL/DL return \n");
|
|
||||||
retVal.type = TYPE_BYTE_SIGN;
|
retVal.type = TYPE_BYTE_SIGN;
|
||||||
retVal.loc = REG_FRAME;
|
retVal.loc = REG_FRAME;
|
||||||
if (isAL)
|
if (isAL)
|
||||||
|
|||||||
@ -30,23 +30,26 @@ void Function::createCFG()
|
|||||||
* 6) End of procedure
|
* 6) End of procedure
|
||||||
*/
|
*/
|
||||||
int i;
|
int i;
|
||||||
int ip, start;
|
int ip;
|
||||||
BB * psBB;
|
BB * psBB;
|
||||||
BB * pBB;
|
BB * pBB;
|
||||||
iICODE pIcode = Icode.begin();
|
iICODE pIcode = Icode.begin();
|
||||||
|
iICODE iStart = Icode.begin();
|
||||||
stats.numBBbef = stats.numBBaft = 0;
|
stats.numBBbef = stats.numBBaft = 0;
|
||||||
for (ip = start = 0; pIcode!=Icode.end(); ip++, pIcode++)
|
for (; pIcode!=Icode.end(); ++pIcode)
|
||||||
{
|
{
|
||||||
|
iICODE nextIcode = ++iICODE(pIcode);
|
||||||
LLInst *ll = pIcode->ll();
|
LLInst *ll = pIcode->ll();
|
||||||
/* Stick a NOWHERE_NODE on the end if we terminate
|
/* Stick a NOWHERE_NODE on the end if we terminate
|
||||||
* with anything other than a ret, jump or terminate */
|
* with anything other than a ret, jump or terminate */
|
||||||
if (ip + 1 == Icode.size() and
|
if (nextIcode == Icode.end() and
|
||||||
(not ll->testFlags(TERMINATES)) and
|
(not ll->testFlags(TERMINATES)) and
|
||||||
(not ll->match(iJMP)) and (not ll->match(iJMPF)) and
|
(not ll->match(iJMP)) and (not ll->match(iJMPF)) and
|
||||||
(not ll->match(iRET)) and (not ll->match(iRETF)))
|
(not ll->match(iRET)) and (not ll->match(iRETF)))
|
||||||
{
|
{
|
||||||
pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this);
|
//pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this);
|
||||||
|
pBB=BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only process icodes that have valid instructions */
|
/* Only process icodes that have valid instructions */
|
||||||
@ -58,10 +61,11 @@ void Function::createCFG()
|
|||||||
case iJE: case iJNE: case iJS: case iJNS:
|
case iJE: case iJNE: case iJS: case iJNS:
|
||||||
case iJO: case iJNO: case iJP: case iJNP:
|
case iJO: case iJNO: case iJP: case iJNP:
|
||||||
case iJCXZ:
|
case iJCXZ:
|
||||||
pBB = BB::Create(start, ip, TWO_BRANCH, 2, this);
|
pBB = BB::Create(iStart, pIcode, TWO_BRANCH, 2, this);
|
||||||
CondJumps:
|
CondJumps:
|
||||||
start = ip + 1;
|
//start = ip + 1;
|
||||||
pBB->edges[0].ip = (uint32_t)start;
|
iStart = ++iICODE(pIcode);
|
||||||
|
pBB->edges[0].ip = (uint32_t)iStart->loc_ip;
|
||||||
/* This is for jumps off into nowhere */
|
/* This is for jumps off into nowhere */
|
||||||
if ( ll->testFlags(NO_LABEL) )
|
if ( ll->testFlags(NO_LABEL) )
|
||||||
{
|
{
|
||||||
@ -72,25 +76,29 @@ CondJumps:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iLOOP: case iLOOPE: case iLOOPNE:
|
case iLOOP: case iLOOPE: case iLOOPNE:
|
||||||
pBB = BB::Create(start, ip, LOOP_NODE, 2, this);
|
//pBB = BB::Create(start, ip, LOOP_NODE, 2, this);
|
||||||
|
pBB = BB::Create(iStart, pIcode, LOOP_NODE, 2, this);
|
||||||
goto CondJumps;
|
goto CondJumps;
|
||||||
|
|
||||||
case iJMPF: case iJMP:
|
case iJMPF: case iJMP:
|
||||||
if (ll->testFlags(SWITCH))
|
if (ll->testFlags(SWITCH))
|
||||||
{
|
{
|
||||||
pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this);
|
//pBB = BB::Create(start, ip, MULTI_BRANCH, ll->caseTbl.numEntries, this);
|
||||||
|
pBB = BB::Create(iStart, pIcode, MULTI_BRANCH, ll->caseTbl.numEntries, this);
|
||||||
for (i = 0; i < ll->caseTbl.numEntries; i++)
|
for (i = 0; i < ll->caseTbl.numEntries; i++)
|
||||||
pBB->edges[i].ip = ll->caseTbl.entries[i];
|
pBB->edges[i].ip = ll->caseTbl.entries[i];
|
||||||
hasCase = true;
|
hasCase = true;
|
||||||
}
|
}
|
||||||
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
|
else if ((ll->getFlag() & (I | NO_LABEL)) == I) //TODO: WHY NO_LABEL TESTIT
|
||||||
{
|
{
|
||||||
pBB = BB::Create(start, ip, ONE_BRANCH, 1, this);
|
//pBB = BB::Create(start, ip, ONE_BRANCH, 1, this);
|
||||||
|
pBB = BB::Create(iStart, pIcode, ONE_BRANCH, 1, this);
|
||||||
|
|
||||||
pBB->edges[0].ip = ll->src.op();
|
pBB->edges[0].ip = ll->src.op();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
BB::Create(start, ip, NOWHERE_NODE, 0, this);
|
BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
|
||||||
start = ip + 1;
|
iStart = ++iICODE(pIcode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iCALLF: case iCALL:
|
case iCALLF: case iCALL:
|
||||||
@ -100,16 +108,17 @@ CondJumps:
|
|||||||
i = ((p->flg) & TERMINATES) ? 0 : 1;
|
i = ((p->flg) & TERMINATES) ? 0 : 1;
|
||||||
else
|
else
|
||||||
i = 1;
|
i = 1;
|
||||||
pBB = BB::Create(start, ip, CALL_NODE, i, this);
|
pBB = BB::Create(iStart, pIcode, CALL_NODE, i, this);
|
||||||
start = ip + 1;
|
iStart = ++iICODE(pIcode);//start = ip + 1;
|
||||||
if (i)
|
if (i)
|
||||||
pBB->edges[0].ip = (uint32_t)start;
|
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iRET: case iRETF:
|
case iRET: case iRETF:
|
||||||
BB::Create(start, ip, RETURN_NODE, 0, this);
|
//BB::Create(start, ip, RETURN_NODE, 0, this);
|
||||||
start = ip + 1;
|
BB::Create(iStart, pIcode, RETURN_NODE, 0, this);
|
||||||
|
iStart = ++iICODE(pIcode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -117,18 +126,20 @@ CondJumps:
|
|||||||
iICODE next1=++iICODE(pIcode);
|
iICODE next1=++iICODE(pIcode);
|
||||||
if ( ll->testFlags(TERMINATES) )
|
if ( ll->testFlags(TERMINATES) )
|
||||||
{
|
{
|
||||||
pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
|
pBB = BB::Create(iStart, pIcode, TERMINATE_NODE, 0, this);
|
||||||
start = ip + 1;
|
//pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
|
||||||
|
iStart = ++iICODE(pIcode); // start = ip + 1;
|
||||||
}
|
}
|
||||||
/* Check for a fall through */
|
/* Check for a fall through */
|
||||||
else if (next1 != Icode.end())
|
else if (next1 != Icode.end())
|
||||||
{
|
{
|
||||||
assert(next1->loc_ip==ip+1);
|
|
||||||
if (next1->ll()->testFlags(TARGET | CASE))
|
if (next1->ll()->testFlags(TARGET | CASE))
|
||||||
{
|
{
|
||||||
pBB = BB::Create(start, ip, FALL_NODE, 1, this);
|
//pBB = BB::Create(start, ip, FALL_NODE, 1, this);
|
||||||
start = ip + 1;
|
pBB = BB::Create(iStart, pIcode, FALL_NODE, 1, this);
|
||||||
pBB->edges[0].ip = (uint32_t)start;
|
iStart = ++iICODE(pIcode); // start = ip + 1;
|
||||||
|
pBB->addOutEdge(iStart->loc_ip);
|
||||||
|
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -142,7 +153,7 @@ CondJumps:
|
|||||||
pBB = *iter;
|
pBB = *iter;
|
||||||
for (size_t edeg_idx = 0; edeg_idx < pBB->edges.size(); edeg_idx++)
|
for (size_t edeg_idx = 0; edeg_idx < pBB->edges.size(); edeg_idx++)
|
||||||
{
|
{
|
||||||
ip = pBB->edges[edeg_idx].ip;
|
uint32_t ip = pBB->edges[edeg_idx].ip;
|
||||||
if (ip >= SYNTHESIZED_MIN)
|
if (ip >= SYNTHESIZED_MIN)
|
||||||
{
|
{
|
||||||
fatalError (INVALID_SYNTHETIC_BB);
|
fatalError (INVALID_SYNTHETIC_BB);
|
||||||
@ -273,13 +284,13 @@ void Function::compressCFG()
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
BB *BB::rmJMP(int marker, BB * pBB)
|
BB *BB::rmJMP(int marker, BB * pBB)
|
||||||
{
|
{
|
||||||
marker += DFS_JMP;
|
marker += (int)DFS_JMP;
|
||||||
|
|
||||||
while (pBB->nodeType == ONE_BRANCH && pBB->size() == 1)
|
while (pBB->nodeType == ONE_BRANCH && pBB->size() == 1)
|
||||||
{
|
{
|
||||||
if (pBB->traversed != marker)
|
if (pBB->traversed != marker)
|
||||||
{
|
{
|
||||||
pBB->traversed = marker;
|
pBB->traversed = (eDFS)marker;
|
||||||
pBB->inEdges.pop_back();
|
pBB->inEdges.pop_back();
|
||||||
if (not pBB->inEdges.empty())
|
if (not pBB->inEdges.empty())
|
||||||
{
|
{
|
||||||
@ -347,15 +358,14 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
|
|||||||
back().ll()->setFlags(NO_CODE);
|
back().ll()->setFlags(NO_CODE);
|
||||||
back().invalidate();
|
back().invalidate();
|
||||||
nodeType = FALL_NODE;
|
nodeType = FALL_NODE;
|
||||||
range_end--;
|
//instructions.advance_end(-1); //TODO: causes creation of empty BB
|
||||||
|
|
||||||
}
|
}
|
||||||
/* If there's no other edges into child can merge */
|
/* If there's no other edges into child can merge */
|
||||||
if (pChild->inEdges.size() != 1)
|
if (pChild->inEdges.size() != 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nodeType = pChild->nodeType;
|
nodeType = pChild->nodeType;
|
||||||
range_end = pChild->range_end;
|
instructions = boost::make_iterator_range(begin(),pChild->end());
|
||||||
pChild->front().ll()->clrFlags(TARGET);
|
pChild->front().ll()->clrFlags(TARGET);
|
||||||
edges.swap(pChild->edges);
|
edges.swap(pChild->edges);
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,14 @@ void CIcodeRec::SetInBB(int start, int _end, BB *pnewBB)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB)
|
||||||
|
{
|
||||||
|
for(ICODE &ic : rang)
|
||||||
|
{
|
||||||
|
ic.inBB = pnewBB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* labelSrchRepl - Searches the icodes for instruction with label = target, and
|
/* labelSrchRepl - Searches the icodes for instruction with label = target, and
|
||||||
replaces *pIndex with an icode index */
|
replaces *pIndex with an icode index */
|
||||||
bool CIcodeRec::labelSrch(uint32_t target, uint32_t &pIndex)
|
bool CIcodeRec::labelSrch(uint32_t target, uint32_t &pIndex)
|
||||||
|
|||||||
@ -176,7 +176,12 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
|
|||||||
id_arr[idx].id.longId.l = regL;
|
id_arr[idx].id.longId.l = regL;
|
||||||
return (idx);
|
return (idx);
|
||||||
}
|
}
|
||||||
|
/* Returns an identifier conditional expression node of type TYPE_LONG or
|
||||||
|
* TYPE_WORD_SIGN */
|
||||||
|
COND_EXPR * LOCAL_ID::createId(const ID *retVal, iICODE ix_)
|
||||||
|
{
|
||||||
|
return COND_EXPR::idID(retVal,this,ix_);
|
||||||
|
}
|
||||||
|
|
||||||
/* Checks if the entry exists in the locSym, if so, returns the idx to this
|
/* Checks if the entry exists in the locSym, if so, returns the idx to this
|
||||||
* entry; otherwise creates a new global identifier node of type
|
* entry; otherwise creates a new global identifier node of type
|
||||||
|
|||||||
@ -92,11 +92,11 @@ void CALL_GRAPH::write()
|
|||||||
/* Updates the argument table by including the register(s) (ie. lhs of
|
/* Updates the argument table by including the register(s) (ie. lhs of
|
||||||
* picode) and the actual expression (ie. rhs of picode).
|
* picode) and the actual expression (ie. rhs of picode).
|
||||||
* Note: register(s) are only included once in the table. */
|
* Note: register(s) are only included once in the table. */
|
||||||
void Function::newRegArg(iICODE picode, iICODE ticode)
|
void LOCAL_ID::newRegArg(iICODE picode, iICODE ticode) const
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs;
|
COND_EXPR *lhs;
|
||||||
STKFRAME * call_args_stackframe, *target_stackframe;
|
STKFRAME * call_args_stackframe, *target_stackframe;
|
||||||
ID *id;
|
const ID *id;
|
||||||
int tidx;
|
int tidx;
|
||||||
boolT regExist;
|
boolT regExist;
|
||||||
condId type;
|
condId type;
|
||||||
@ -114,7 +114,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
|
|||||||
type = lhs->expr.ident.idType;
|
type = lhs->expr.ident.idType;
|
||||||
if (type == REGISTER)
|
if (type == REGISTER)
|
||||||
{
|
{
|
||||||
regL = localId.id_arr[lhs->expr.ident.idNode.regiIdx].id.regi;
|
regL = id_arr[lhs->expr.ident.idNode.regiIdx].id.regi;
|
||||||
if (regL < rAL)
|
if (regL < rAL)
|
||||||
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
||||||
else
|
else
|
||||||
@ -122,28 +122,28 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
|
|||||||
}
|
}
|
||||||
else if (type == LONG_VAR)
|
else if (type == LONG_VAR)
|
||||||
{
|
{
|
||||||
regL = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l;
|
int longIdx = lhs->expr.ident.idNode.longIdx;
|
||||||
regH = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h;
|
regL = id_arr[longIdx].id.longId.l;
|
||||||
|
regH = id_arr[longIdx].id.longId.h;
|
||||||
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/);
|
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, tproc->Icode.begin() /*0*/);
|
||||||
//tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, Icode.begin() /*0*/);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if register argument already on the formal argument list */
|
/* Check if register argument already on the formal argument list */
|
||||||
regExist = false;
|
regExist = false;
|
||||||
for(STKSYM &tgt_sym : *target_stackframe)
|
for(STKSYM &tgt_sym : *target_stackframe)
|
||||||
{
|
{
|
||||||
|
if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition
|
||||||
|
continue;
|
||||||
if (type == REGISTER)
|
if (type == REGISTER)
|
||||||
{
|
{
|
||||||
if ((tgt_sym.regs != NULL) &&
|
if ( tgt_sym.regs->expr.ident.idNode.regiIdx == tidx )
|
||||||
(tgt_sym.regs->expr.ident.idNode.regiIdx == tidx))
|
|
||||||
{
|
{
|
||||||
regExist = true;
|
regExist = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == LONG_VAR)
|
else if (type == LONG_VAR)
|
||||||
{
|
{
|
||||||
if ((tgt_sym.regs != NULL) &&
|
if ( tgt_sym.regs->expr.ident.idNode.longIdx == tidx )
|
||||||
(tgt_sym.regs->expr.ident.idNode.longIdx == tidx))
|
|
||||||
{
|
{
|
||||||
regExist = true;
|
regExist = true;
|
||||||
}
|
}
|
||||||
@ -192,7 +192,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
|
|||||||
/* Mask off high and low register(s) in picode */
|
/* Mask off high and low register(s) in picode */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case REGISTER:
|
case REGISTER:
|
||||||
id = &localId.id_arr[lhs->expr.ident.idNode.regiIdx];
|
id = &id_arr[lhs->expr.ident.idNode.regiIdx];
|
||||||
picode->du.def &= maskDuReg[id->id.regi];
|
picode->du.def &= maskDuReg[id->id.regi];
|
||||||
if (id->id.regi < rAL)
|
if (id->id.regi < rAL)
|
||||||
newsym.type = TYPE_WORD_SIGN;
|
newsym.type = TYPE_WORD_SIGN;
|
||||||
@ -200,7 +200,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
|
|||||||
newsym.type = TYPE_BYTE_SIGN;
|
newsym.type = TYPE_BYTE_SIGN;
|
||||||
break;
|
break;
|
||||||
case LONG_VAR:
|
case LONG_VAR:
|
||||||
id = &localId.id_arr[lhs->expr.ident.idNode.longIdx];
|
id = &id_arr[lhs->expr.ident.idNode.longIdx];
|
||||||
picode->du.def &= maskDuReg[id->id.longId.h];
|
picode->du.def &= maskDuReg[id->id.longId.h];
|
||||||
picode->du.def &= maskDuReg[id->id.longId.l];
|
picode->du.def &= maskDuReg[id->id.longId.l];
|
||||||
newsym.type = TYPE_LONG_SIGN;
|
newsym.type = TYPE_LONG_SIGN;
|
||||||
@ -252,6 +252,11 @@ void CallType::placeStkArg (COND_EXPR *exp, int pos)
|
|||||||
(*args)[pos].setArgName(pos);
|
(*args)[pos].setArgName(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COND_EXPR *CallType::toId()
|
||||||
|
{
|
||||||
|
return COND_EXPR::idFunc( proc, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Checks to determine whether the expression (actual argument) has the
|
/* Checks to determine whether the expression (actual argument) has the
|
||||||
* same type as the given type (from the procedure's formal list). If not,
|
* same type as the given type (from the procedure's formal list). If not,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user