Using boost now
This commit is contained in:
parent
a740690e04
commit
4dd97b0709
@ -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;
|
||||
|
||||
};
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -30,6 +30,7 @@ public:
|
||||
}
|
||||
strTable decl; /* Declarations */
|
||||
strTable code; /* C code */
|
||||
int current_indent;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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_);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@ -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() );
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
563
src/dataflow.cpp
563
src/dataflow.cpp
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user