Using boost now

This commit is contained in:
Artur K 2012-03-15 18:55:27 +01:00
parent a740690e04
commit 4dd97b0709
16 changed files with 553 additions and 437 deletions

View File

@ -5,6 +5,8 @@
#include <string>
#include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h>
#include <boost/range.hpp>
#include "icode.h"
#include "types.h"
#include "graph.h"
//#include "icode.h"
@ -12,22 +14,21 @@
struct Function;
class CIcodeRec;
struct BB;
struct LOCAL_ID;
struct interval;
struct ICODE;
typedef std::list<ICODE>::iterator iICODE;
typedef std::list<ICODE>::reverse_iterator riICODE;
typedef union
struct TYPEADR_TYPE
{
uint32_t ip; /* Out edge icode address */
BB * BBptr; /* Out edge pointer to next BB */
interval *intPtr; /* Out edge ptr to next interval*/
} TYPEADR_TYPE;
};
struct BB : public llvm::ilist_node<BB>
{
private:
BB(const BB&);
BB() : nodeType(0),traversed(0),
BB() : nodeType(0),traversed(DFS_NONE),
numHlIcodes(0),flg(0),
inEdges(0),
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
@ -38,10 +39,14 @@ private:
}
//friend class SymbolTableListTraits<BB, Function>;
iICODE range_start;
iICODE range_end;
typedef boost::iterator_range<iICODE> rCODE;
rCODE instructions;
public:
struct ValidFunctor
{
bool operator()(BB *p) {return p->valid();}
};
iICODE begin();
iICODE end() const;
riICODE rbegin();
@ -50,7 +55,7 @@ public:
ICODE &back();
size_t size();
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 */
uint32_t flg; /* BB flags */
@ -94,8 +99,9 @@ public:
int caseTail; /* tail node for the case */
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(int start, int ip, uint8_t nodeType, int numOutEdges, Function * parent);
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(iICODE start, iICODE fin, uint8_t _nodeType, int numOutEdges, Function *parent);
void writeCode(int indLevel, Function *pProc, int *numLoc, int latchNode, int ifFollow);
void mergeFallThrough(CIcodeRec &Icode);
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; }
Function *getParent() { return Parent; }
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
BB *rmJMP(int marker, BB *pBB);
void genDU1();
void writeBB(std::ostream &ostr, int lev, Function *pProc, int *numLoc);
BB * rmJMP(int marker, BB *pBB);
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:
bool isEndOfPath(int latch_node_idx) const;
Function *Parent;
};

View File

@ -124,6 +124,9 @@ public:
r->name = nm;
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 writeProcComments();
void lowLevelAnalysis();
@ -140,10 +143,8 @@ public:
void process_operands(ICODE &pIcode, STATE *pstate);
boolT process_JMP(ICODE &pIcode, STATE *pstate, CALL_GRAPH *pcallGraph);
boolT process_CALL(ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
void displayCFG();
void freeCFG();
void codeGen(std::ostream &fs);
void displayStats();
void mergeFallThrough(BB *pBB);
void structIfs();
void structLoops(derSeq *derivedG);
@ -151,20 +152,25 @@ public:
void controlFlowAnalysis();
void newRegArg(iICODE picode, iICODE ticode);
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_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);
void replaceInEdge(BB* where, BB* which, BB* with);
protected:
bool removeInEdge_Flag_and_ProcessLatch(BB *pbb, BB *a, BB *b);
void processExpPush(int &numHlIcodes, iICODE picode);
// TODO: replace those with friend visitor ?
void propLongReg(int loc_ident_idx, const ID &pLocId);
void propLongStk(int i, const ID &pLocId);
void propLongGlb(int i, const ID &pLocId);
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 findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg);
@ -176,6 +182,6 @@ public:
void findIdioms();
void propLong();
void genLiveKtes();
uint8_t findDerivedSeq (derSeq &derivedGi);
uint8_t findDerivedSeq (derSeq &derivedGi);
bool nextOrderGraph(derSeq &derivedGi);
};

View File

@ -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 *boolOp(COND_EXPR *_lhs, COND_EXPR *_rhs, condOp _op);
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:
virtual COND_EXPR *clone() const;
void release();
@ -105,8 +105,8 @@ public:
virtual ~COND_EXPR() {}
public:
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 COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, LOCAL_ID *locsym);
virtual bool xClear(iICODE f, iICODE t, iICODE lastBBinst, const LOCAL_ID &locId);
virtual COND_EXPR *insertSubTreeReg(COND_EXPR *_expr, eReg regi, const LOCAL_ID *locsym);
virtual COND_EXPR *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
virtual hlType expType(Function *pproc) const;
};
@ -124,7 +124,7 @@ struct BinaryOperator : public COND_EXPR
static BinaryOperator *CreateAdd(COND_EXPR *l,COND_EXPR *r);
virtual COND_EXPR *inverse();
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 *insertSubTreeLongReg(COND_EXPR *_expr, int longIdx);
@ -158,7 +158,7 @@ struct UnaryOperator : public COND_EXPR
COND_EXPR *unaryExp;
virtual COND_EXPR *inverse();
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)
{
UnaryOperator *newExp = new UnaryOperator();

View File

@ -30,6 +30,7 @@ public:
}
strTable decl; /* Declarations */
strTable code; /* C code */
int current_indent;
};

View File

@ -28,6 +28,7 @@ enum eBBKind
/* Depth-first traversal constants */
enum eDFS
{
DFS_NONE,
DFS_DISP=1, /* Display graph pass */
DFS_MERGE=2, /* Merge nodes pass */
DFS_NUM=3, /* DFS numbering pass */

View File

@ -13,6 +13,7 @@
#include <llvm/MC/MCInst.h>
#include <llvm/MC/MCAsmInfo.h>
#include <llvm/Value.h>
#include <boost/range.hpp>
#include "Enums.h"
#include "state.h" // State depends on INDEXBASE, but later need STATE
//enum condId;
@ -26,6 +27,7 @@ struct ICODE;
struct bundle;
typedef std::list<ICODE>::iterator iICODE;
typedef std::list<ICODE>::reverse_iterator riICODE;
typedef boost::iterator_range<iICODE> rCODE;
/* uint8_t and uint16_t registers */
@ -58,6 +60,7 @@ struct CallType : public HlTypeSupport
void allocStkArgs (int num);
bool newStkArg(COND_EXPR *exp, llIcode opcode, Function *pproc);
void placeStkArg(COND_EXPR *exp, int pos);
virtual COND_EXPR * toId();
public:
bool removeRegFromLong(eReg regi, LOCAL_ID *locId)
{
@ -285,6 +288,18 @@ protected:
HLTYPE m_hl;
bool invalid; /* Has no HIGH_LEVEL equivalent */
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 */
struct DU_ICODE
{
@ -399,6 +414,7 @@ public:
ICODE * addIcode(ICODE *pIcode);
void SetInBB(int start, int end, BB* pnewBB);
void SetInBB(rCODE &rang, BB* pnewBB);
bool labelSrch(uint32_t target, uint32_t &pIndex);
iterator labelSrch(uint32_t target);
ICODE * GetIcode(int ip);

View File

@ -18,6 +18,7 @@
/* Type definition */
// this array has to stay in-order of addition i.e. not std::set<iICODE,std::less<iICODE> >
// TODO: why ?
struct COND_EXPR;
struct ICODE;
typedef std::list<ICODE>::iterator iICODE;
struct IDX_ARRAY : public std::vector<iICODE>
@ -104,6 +105,10 @@ struct ID
struct LOCAL_ID
{
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:
LOCAL_ID()
{
@ -122,10 +127,10 @@ public:
void flagByteWordId(int off);
void propLongId(uint8_t regL, uint8_t regH, const char *name);
size_t csym() const {return id_arr.size();}
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);
void newRegArg(iICODE picode, iICODE ticode) const;
void processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode, bool isLong) const;
void forwardSubs(COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const;
COND_EXPR *createId(const ID *retVal, iICODE ix_);
};

View File

@ -50,7 +50,7 @@ struct STKSYM : public SymbolCommon
void setArgName(int i)
{
char buf[32];
sprintf (buf, "arg%ld", i);
sprintf (buf, "arg%d", i);
name = buf;
}
};

View File

@ -1,10 +1,13 @@
#include <cassert>
#include <string>
#include <boost/range/rbegin.hpp>
#include <boost/range/rend.hpp>
#include <boost/range/adaptors.hpp>
#include "BasicBlock.h"
#include "Procedure.h"
#include "dcc.h"
using namespace std;
using namespace boost;
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;
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;
pnewBB = new BB;
pnewBB->nodeType = _nodeType; /* Initialise */
pnewBB->immedDom = NO_DOM;
pnewBB->loopHead = pnewBB->caseHead = pnewBB->caseTail =
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
pnewBB->range_start = parent->Icode.begin();
pnewBB->range_end = parent->Icode.begin();
if(start!=-1)
pnewBB->latchNode= pnewBB->loopFollow = NO_NODE;
pnewBB->instructions = make_iterator_range(start,fin);
if(start==parent->Icode.end())
{
advance(pnewBB->range_start,start);
advance(pnewBB->range_end,ip+1);
pnewBB->instructions = make_iterator_range(parent->Icode.end(),parent->Icode.end());
}
else
{
pnewBB->range_end = parent->Icode.end();
pnewBB->range_end = parent->Icode.end();
pnewBB->instructions.advance_end(1); // 1 after fin, to create range where fin is inclusive
}
if (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) */
if(parent)
{
if (start >= 0)
parent->Icode.SetInBB(start, ip, pnewBB);
if (start != parent->Icode.end())
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
parent->heldBBs.push_back(pnewBB);
parent->m_cfg.push_back(pnewBB);
pnewBB->Parent = parent;
}
if (start != -1) /* Only for code BB's */
if ( start != parent->Icode.end() ) /* Only for code BB's */
stats.numBBbef++;
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",
"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());
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
@ -131,11 +153,63 @@ void BB::displayDfs()
* current procedure.
* indLevel: indentation level - used for formatting.
* 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)
{
int follow, /* ifFollow */
_loopType, /* Type of loop, if any */
_nodeType; /* Type of node */
int follow; /* ifFollow */
BB * succ, *latch; /* Successor and latching node */
ICODE * picode; /* Pointer to HLI_JCOND instruction */
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]))
return;
if (traversed == DFS_ALPHA)
if (wasTraversedAtLevel(DFS_ALPHA))
return;
traversed = DFS_ALPHA;
/* Check for start of loop */
repCond = false;
latch = NULL;
_loopType = loopType;
if (_loopType)
if (loopType)
{
latch = pProc->m_dfsLast[this->latchNode];
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++;
picode=writeLoopHeader(indLevel, pProc, numLoc, latch, repCond);
}
/* 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 */
_nodeType = nodeType;
if (_nodeType == RETURN_NODE || _nodeType == TERMINATE_NODE ||
_nodeType == NOWHERE_NODE || (dfsLastNum == _latchNode))
if (isEndOfPath(_latchNode))
return;
/* Check type of loop/node and process code */
if (_loopType) /* there is a loop */
if ( loopType) /* there is a loop */
{
assert(latch);
if (this != latch) /* loop is over several bbs */
{
if (_loopType == WHILE_TYPE)
if (loopType == WHILE_TYPE)
{
succ = edges[THEN].BBptr;
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 */
indLevel--;
if (_loopType == WHILE_TYPE)
if (loopType == WHILE_TYPE)
{
std::ostringstream ostr;
/* 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";
cCode.appendCode(ostr.str());
}
else if (_loopType == ENDLESS_TYPE)
else if (loopType == ENDLESS_TYPE)
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)
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 */
{
if (_nodeType == TWO_BRANCH) /* if-then[-else] */
if (nodeType == TWO_BRANCH) /* if-then[-else] */
{
stats.numHLIcode++;
indLevel++;
@ -344,8 +372,11 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
else /* fall, call, 1w */
{
succ = edges[0].BBptr; /* fall-through edge */
assert(succ->size()>0);
if (succ->traversed != DFS_ALPHA)
{
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 */
for(ICODE &pHli : *this)
for(ICODE &pHli : instructions)
{
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()
{
return range_start;
return instructions.begin();//range_start;
}
iICODE BB::end() const
{
return range_end;
return instructions.end();//range_end
}
ICODE &BB::back()
{
return *rbegin();
return instructions.back();//*rbegin();
}
size_t BB::size()
{
return distance(range_start,range_end);
return distance(instructions.begin(),instructions.end());
}
ICODE &BB::front()
{
return *begin();
return instructions.front();//*begin();
}
riICODE BB::rbegin()
{
return riICODE(end());
return riICODE( instructions.end() );
}
riICODE BB::rend()
{
return riICODE(begin());
return riICODE( instructions.begin() );
}

View File

@ -823,7 +823,7 @@ void COND_EXPR::changeBoolOp (condOp newOp)
/* Inserts the expression exp into the tree at the location specified by the
* 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)
@ -836,7 +836,7 @@ bool COND_EXPR::insertSubTreeReg (COND_EXPR *&tree, COND_EXPR *_expr, eReg regi,
}
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;

View File

@ -2,14 +2,16 @@
* Description : Performs control flow analysis on the CFG
* (C) Cristina Cifuentes
********************************************************************/
#include <boost/range/algorithm.hpp>
#include <algorithm>
#include <list>
#include <cassert>
#include "dcc.h"
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "dcc.h"
//typedef struct list {
// int nodeIdx;
// 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));
/* Replace in-edge to obb from t to pbb */
auto iter=find(obb->inEdges.begin(),obb->inEdges.end(),thenBB);
if(iter!=obb->inEdges.end())
*iter = pbb;

View File

@ -9,6 +9,7 @@
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/assign.hpp>
#include <string.h>
#include <iostream>
#include <iomanip>
@ -24,6 +25,13 @@ struct ExpStack
COND_EXPR * pop();
int numElem();
boolT empty();
void processExpPush(int &numHlIcodes, iICODE picode)
{
push(picode->hl()->expr());
picode->invalidate();
numHlIcodes--;
}
};
/***************************************************************************
* Expression stack functions
@ -266,6 +274,8 @@ void Function::genLiveKtes ()
* Propagates register usage information to the procedure call. */
void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
{
using namespace boost::adaptors;
using namespace boost::assign;
BB * pbb=0; /* pointer to current basic block */
Function * pcallee; /* invoked 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 */
change = false;
//for (i = numBBs; i > 0; i--)
//boost::RandomAccessContainerConcept;
for(auto iBB=m_dfsLast.rbegin(); iBB!=m_dfsLast.rend(); ++iBB)
auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
for( BB * _pbb : valid_reversed_bbs)
{
pbb = *iBB;//m_dfsLast[i-1];
if (pbb->flg & INVALID_BB) /* Do not process invalid BBs */
continue;
pbb = _pbb;//*iBB;//m_dfsLast[i-1];
/* Get current liveIn() and liveOut() sets */
prevLiveIn = pbb->liveIn;
@ -307,7 +313,6 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
auto picode = pbb->rbegin(); /* icode of function return */
if (picode->hl()->opcode == HLI_RET)
{
//pbb->back().loc_ip
picode->hl()->expr(COND_EXPR::idID (&retVal, &localId, (++pbb->rbegin()).base()));
picode->du.use = in_liveOut;
}
@ -393,6 +398,7 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
void BB::genDU1()
{
using namespace boost::adaptors;
eReg regi; /* Register that was defined */
int k, defRegIdx, useIdx;
iICODE picode, ticode,lastInst;
@ -404,10 +410,13 @@ void BB::genDU1()
*/
assert(0!=Parent);
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)
continue;
// if (picode->type != HIGH_LEVEL)
// continue;
regi = rUNDEF;
defRegIdx = 0;
// foreach defined register
@ -428,10 +437,10 @@ void BB::genDU1()
continue;
if ((regi == rSI) && (flg & SI_REGVAR))
continue;
if (distance(picode,lastInst)>1) /* several instructions */
if (distance(picode,all_high_levels.end())>1) /* several instructions */
{
useIdx = 0;
for (auto ricode = ++iICODE(picode); ricode != lastInst; ricode++)
for (auto ricode = ++iICODE(picode.base()); ricode != lastInst; ricode++)
{
ticode=ricode;
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
* 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 */
@ -536,18 +545,15 @@ void Function::genDU1 ()
/* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
* of picode. */
static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode,
iICODE ticode, LOCAL_ID *locsym, int &numHlIcodes)
void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
{
boolT res;
bool res;
if (rhs == NULL) /* In case expression popped is NULL */
return;
/* Insert on rhs of ticode, if possible */
res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs,
locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi,
locsym);
res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this);
if (res)
{
picode->invalidate();
@ -556,9 +562,7 @@ static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode,
else
{
/* Try to insert it on lhs of ticode*/
res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs,
locsym->id_arr[lhs->expr.ident.idNode.regiIdx].id.regi,
locsym);
res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this);
if (res)
{
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
* 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;
boolT res;
@ -610,7 +614,7 @@ bool COND_EXPR::xClear (iICODE f, iICODE t, iICODE lastBBinst, Function * pproc)
case IDENTIFIER:
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++)
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:
if(0==rhs())
return false;
res = rhs()->xClear ( f, t, lastBBinst, pproc);
res = rhs()->xClear ( f, t, lastBBinst, locId);
if (res == false)
return false;
if(0==lhs())
return false;
return lhs()->xClear ( f, t, lastBBinst, pproc);
return lhs()->xClear ( f, t, lastBBinst, locId);
case NEGATION:
case ADDRESSOF:
case DEREFERENCE:
if(0==expr.unaryExp)
return false;
return expr.unaryExp->xClear ( f, t, lastBBinst, pproc);
return expr.unaryExp->xClear ( f, t, lastBBinst, locId);
} /* eos */
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)
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)
return false;
if ( ! m_rhs->xClear (f, t, lastBBinst, pproc) )
if ( ! m_rhs->xClear (f, t, lastBBinst, locs) )
return false;
if(0==m_lhs)
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,
* 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
* expressions. Generates new hlIcodes in the form of expression trees.
* 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;
switch (ticode->hl()->opcode) {
HLTYPE &p_hl(*picode->hl());
HLTYPE &t_hl(*ticode->hl());
switch (t_hl.opcode)
{
case HLI_ASSIGN:
if(isLong)
{
forwardSubsLong (picode->hl()->asgn.lhs->expr.ident.idNode.longIdx,
picode->hl()->asgn.rhs, picode,ticode,
forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx,
p_hl.asgn.rhs, picode,ticode,
&numHlIcodes);
}
else
forwardSubs (picode->hl()->asgn.lhs, picode->hl()->asgn.rhs,
picode, ticode, &localId, numHlIcodes);
this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes);
break;
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
if(isLong)
{
res = COND_EXPR::insertSubTreeLongReg (
picode->hl()->asgn.rhs,
&ticode->hl()->exp.v,
picode->hl()->asgn.lhs->expr.ident.idNode.longIdx);
p_hl.asgn.rhs,
&t_hl.exp.v,
p_hl.asgn.lhs->expr.ident.idNode.longIdx);
}
else
{
res = COND_EXPR::insertSubTreeReg (
ticode->hl()->exp.v,
picode->hl()->asgn.rhs,
localId.id_arr[picode->hl()->asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
&localId);
t_hl.exp.v,
p_hl.asgn.rhs,
id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
this);
}
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;
iICODE
picode, // Current icode */
ticode; // Target icode */
BB * pbb; // Current and next basic block */
boolT res;
bool res;
ID *_retVal; // function return value
COND_EXPR *_exp, // expression pointer - for HLI_POP and HLI_CALL */
*lhs; // exp ptr for return value of a HLI_CALL */
//STKFRAME * args; // pointer to arguments - for HLI_CALL */
uint8_t regi; // register(s) to be forward substituted */
ID *_retVal; // function return value
/* Initialize expression stack */
g_exp_stk.init();
_exp = 0;
/* Traverse tree in dfsLast order */
for (i = 0; i < numBBs; i++)
iICODE ticode; // Target icode */
HLTYPE *ti_hl=0;
uint8_t regi;
numHlIcodes = 0;
// register(s) to be forward substituted */
for (iICODE picode = begin(); picode != end(); picode++)
{
/* Process one BB */
pbb = m_dfsLast[i];
if (pbb->flg & INVALID_BB)
if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() ))
continue;
numHlIcodes = 0;
for (picode = pbb->begin(); picode != pbb->end(); picode++)
HLTYPE &_icHl(*picode->hl());
numHlIcodes++;
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
{
if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() ))
continue;
numHlIcodes++;
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
/* Check for only one use of this register. If this is
* the last definition of the register in this BB, check
* that it is not liveOut from this basic block */
if (picode->du1.numUses(0)==1)
{
/* Check for only one use of this register. If this is
* the last definition of the register in this BB, check
* that it is not liveOut from this basic block */
if (picode->du1.numUses(0)==1)
/* Check that this register is not liveOut, if it
* is the last definition of the register */
regi = picode->du1.regi[0];
/* Check if we can forward substitute this register */
switch (_icHl.opcode)
{
/* Check that this register is not liveOut, if it
* is the last definition of the register */
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
case HLI_ASSIGN:
/* Replace rhs of current icode into target
* 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();
if ((picode->du.lastDefRegi & duReg[regi]).any() &&
((ticode->hl()->opcode != HLI_CALL) &&
(ticode->hl()->opcode != HLI_RET)))
continue;
if (picode->hl()->asgn.rhs->xClear (picode,
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 */
_exp = g_exp_stk.pop(); /* pop last exp pushed */
switch (ticode->hl()->opcode) {
case HLI_ASSIGN:
forwardSubs (picode->hl()->expr(), _exp,
picode, ticode, &localId,
numHlIcodes);
forwardSubsLong (_icHl.expr()->expr.ident.idNode.longIdx,
_exp, picode, ticode, &numHlIcodes);
break;
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
res = COND_EXPR::insertSubTreeReg (ticode->hl()->exp.v,
_exp,
localId.id_arr[picode->hl()->expr()->expr.ident.idNode.regiIdx].id.regi,
&localId);
case HLI_JCOND: case HLI_PUSH:
res = COND_EXPR::insertSubTreeLongReg (_exp,
&ticode->hl()->exp.v,
_icHl.asgn.lhs->expr.ident.idNode.longIdx);
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();
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);
}
case HLI_CALL: /*** missing ***/
break;
} /* eos */
break;
} /* eos */
}
}
}
break;
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
case HLI_CALL: /* check for function return */
ticode = picode->du1.idx[0].uses.front();
switch (ticode->hl()->opcode)
{
case HLI_ASSIGN:
_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_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;
processTargetIcode(picode, numHlIcodes, ticode,true);
}
break;
case HLI_PUSH: case HLI_RET:
ticode->hl()->expr( _icHl.call.toId() );
picode->invalidate();
numHlIcodes--;
break;
case HLI_POP:
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;
_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;
case HLI_JCOND:
_exp = _icHl.call.toId();
_retVal = &picode->hl()->call.proc->retVal;
res = COND_EXPR::insertSubTreeLongReg (_exp,
&ticode->hl()->exp.v,
locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
_retVal->id.longId.l, picode));
if (res) /* was substituted */
{
picode->invalidate();
numHlIcodes--;
break;
case HLI_PUSH: case HLI_RET:
ticode->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);
_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 */
}
}
else /* cannot substitute function */
{
lhs = locals.createId(_retVal,picode);
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.
* Push the associated expression to the register on the local
* expression stack */
else if (picode->hl()->opcode == HLI_PUSH)
/* 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(_icHl.opcode == HLI_CALL)
{
if ( not _icHl.call.proc->hasRegArgs())
{
g_exp_stk.push(picode->hl()->expr());
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);
fnc->processHliCall(_exp, picode);
}
/* If we could not substitute the result of a function,
* assign it to the corresponding registers */
if ((picode->hl()->opcode == HLI_CALL) &&
((picode->hl()->call.proc->flg & PROC_ISLIB) !=
PROC_ISLIB) && (not picode->du1.used(0)) &&
(picode->du1.numRegsDef > 0))
if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0))
{
_exp = COND_EXPR::idFunc (picode->hl()->call.proc, picode->hl()->call.args);
lhs = COND_EXPR::idID (&picode->hl()->call.proc->retVal, &localId, picode);
_exp = COND_EXPR::idFunc (_icHl.call.proc, _icHl.call.args);
lhs = COND_EXPR::idID (&_icHl.call.proc->retVal, &locals, picode);
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)
{
isAx = true;
printf("**************************************************************************** dataFlow Join discovered Ax\n");
isAH=isAL=false;
}
if(isDL && isDH)
{
isDx = true;
printf("**************************************************************************** dataFlow Join discovered Dx\n");
isDH=isDL=false;
}
if(isBL && isBH)
{
isBx = true;
printf("**************************************************************************** dataFlow Join discovered Dx\n");
isBH=isBL=false;
}
if(isCL && isCH)
{
isCx = true;
printf("**************************************************************************** dataFlow Join discovered Dx\n");
isCH=isCL=false;
}
@ -1173,7 +1183,6 @@ void Function::dataFlow(std::bitset<32> &_liveOut)
}
else if(isAL||isBL||isCL||isDL)
{
printf("**************************************************************************** AL/DL return \n");
retVal.type = TYPE_BYTE_SIGN;
retVal.loc = REG_FRAME;
if (isAL)

View File

@ -30,23 +30,26 @@ void Function::createCFG()
* 6) End of procedure
*/
int i;
int ip, start;
int ip;
BB * psBB;
BB * pBB;
iICODE pIcode = Icode.begin();
iICODE iStart = Icode.begin();
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();
/* Stick a NOWHERE_NODE on the end if we 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->match(iJMP)) and (not ll->match(iJMPF)) and
(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 */
@ -58,10 +61,11 @@ void Function::createCFG()
case iJE: case iJNE: case iJS: case iJNS:
case iJO: case iJNO: case iJP: case iJNP:
case iJCXZ:
pBB = BB::Create(start, ip, TWO_BRANCH, 2, this);
pBB = BB::Create(iStart, pIcode, TWO_BRANCH, 2, this);
CondJumps:
start = ip + 1;
pBB->edges[0].ip = (uint32_t)start;
//start = ip + 1;
iStart = ++iICODE(pIcode);
pBB->edges[0].ip = (uint32_t)iStart->loc_ip;
/* This is for jumps off into nowhere */
if ( ll->testFlags(NO_LABEL) )
{
@ -72,25 +76,29 @@ CondJumps:
break;
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;
case iJMPF: case iJMP:
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++)
pBB->edges[i].ip = ll->caseTbl.entries[i];
hasCase = true;
}
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();
}
else
BB::Create(start, ip, NOWHERE_NODE, 0, this);
start = ip + 1;
BB::Create(iStart, pIcode, NOWHERE_NODE, 0, this);
iStart = ++iICODE(pIcode);
break;
case iCALLF: case iCALL:
@ -100,16 +108,17 @@ CondJumps:
i = ((p->flg) & TERMINATES) ? 0 : 1;
else
i = 1;
pBB = BB::Create(start, ip, CALL_NODE, i, this);
start = ip + 1;
pBB = BB::Create(iStart, pIcode, CALL_NODE, i, this);
iStart = ++iICODE(pIcode);//start = ip + 1;
if (i)
pBB->edges[0].ip = (uint32_t)start;
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
}
break;
case iRET: case iRETF:
BB::Create(start, ip, RETURN_NODE, 0, this);
start = ip + 1;
//BB::Create(start, ip, RETURN_NODE, 0, this);
BB::Create(iStart, pIcode, RETURN_NODE, 0, this);
iStart = ++iICODE(pIcode);
break;
default:
@ -117,18 +126,20 @@ CondJumps:
iICODE next1=++iICODE(pIcode);
if ( ll->testFlags(TERMINATES) )
{
pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
start = ip + 1;
pBB = BB::Create(iStart, pIcode, TERMINATE_NODE, 0, this);
//pBB = BB::Create(start, ip, TERMINATE_NODE, 0, this);
iStart = ++iICODE(pIcode); // start = ip + 1;
}
/* Check for a fall through */
else if (next1 != Icode.end())
{
assert(next1->loc_ip==ip+1);
if (next1->ll()->testFlags(TARGET | CASE))
{
pBB = BB::Create(start, ip, FALL_NODE, 1, this);
start = ip + 1;
pBB->edges[0].ip = (uint32_t)start;
//pBB = BB::Create(start, ip, FALL_NODE, 1, this);
pBB = BB::Create(iStart, pIcode, FALL_NODE, 1, this);
iStart = ++iICODE(pIcode); // start = ip + 1;
pBB->addOutEdge(iStart->loc_ip);
pBB->edges[0].ip = iStart->loc_ip;//(uint32_t)start;
}
}
break;
@ -142,7 +153,7 @@ CondJumps:
pBB = *iter;
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)
{
fatalError (INVALID_SYNTHETIC_BB);
@ -273,13 +284,13 @@ void Function::compressCFG()
***************************************************************************/
BB *BB::rmJMP(int marker, BB * pBB)
{
marker += DFS_JMP;
marker += (int)DFS_JMP;
while (pBB->nodeType == ONE_BRANCH && pBB->size() == 1)
{
if (pBB->traversed != marker)
{
pBB->traversed = marker;
pBB->traversed = (eDFS)marker;
pBB->inEdges.pop_back();
if (not pBB->inEdges.empty())
{
@ -347,15 +358,14 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
back().ll()->setFlags(NO_CODE);
back().invalidate();
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 (pChild->inEdges.size() != 1)
break;
nodeType = pChild->nodeType;
range_end = pChild->range_end;
instructions = boost::make_iterator_range(begin(),pChild->end());
pChild->front().ll()->clrFlags(TARGET);
edges.swap(pChild->edges);

View File

@ -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
replaces *pIndex with an icode index */
bool CIcodeRec::labelSrch(uint32_t target, uint32_t &pIndex)

View File

@ -176,7 +176,12 @@ int LOCAL_ID::newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_)
id_arr[idx].id.longId.l = regL;
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
* entry; otherwise creates a new global identifier node of type

View File

@ -92,11 +92,11 @@ void CALL_GRAPH::write()
/* Updates the argument table by including the register(s) (ie. lhs of
* picode) and the actual expression (ie. rhs of picode).
* 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;
STKFRAME * call_args_stackframe, *target_stackframe;
ID *id;
const ID *id;
int tidx;
boolT regExist;
condId type;
@ -114,7 +114,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
type = lhs->expr.ident.idType;
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)
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
else
@ -122,28 +122,28 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
}
else if (type == LONG_VAR)
{
regL = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l;
regH = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h;
int longIdx = lhs->expr.ident.idNode.longIdx;
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, Icode.begin() /*0*/);
}
/* Check if register argument already on the formal argument list */
regExist = false;
for(STKSYM &tgt_sym : *target_stackframe)
{
if( tgt_sym.regs == NULL ) // both REGISTER and LONG_VAR require this precondition
continue;
if (type == REGISTER)
{
if ((tgt_sym.regs != NULL) &&
(tgt_sym.regs->expr.ident.idNode.regiIdx == tidx))
if ( tgt_sym.regs->expr.ident.idNode.regiIdx == tidx )
{
regExist = true;
}
}
else if (type == LONG_VAR)
{
if ((tgt_sym.regs != NULL) &&
(tgt_sym.regs->expr.ident.idNode.longIdx == tidx))
if ( tgt_sym.regs->expr.ident.idNode.longIdx == tidx )
{
regExist = true;
}
@ -192,7 +192,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
/* Mask off high and low register(s) in picode */
switch (type) {
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];
if (id->id.regi < rAL)
newsym.type = TYPE_WORD_SIGN;
@ -200,7 +200,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
newsym.type = TYPE_BYTE_SIGN;
break;
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.l];
newsym.type = TYPE_LONG_SIGN;
@ -252,6 +252,11 @@ void CallType::placeStkArg (COND_EXPR *exp, int 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
* same type as the given type (from the procedure's formal list). If not,