from work
This commit is contained in:
parent
4c249fe5c4
commit
900438c453
19
CMakeLists.txt
Executable file → Normal file
19
CMakeLists.txt
Executable file → Normal file
@ -1,16 +1,24 @@
|
||||
#CC = gcc -g -O -D__UNIX__
|
||||
PROJECT(dcc_original)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
SET(CMAKE_BUILD_TYPE Debug)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__)
|
||||
INCLUDE_DIRECTORIES(include ${Boost_INCLUDE_DIRS})
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS)
|
||||
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
add_definitions(/W4)
|
||||
else()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-D_GLIBCXX_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}" )
|
||||
endif()
|
||||
|
||||
FIND_PACKAGE(LLVM)
|
||||
FIND_PACKAGE(Boost)
|
||||
llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native)
|
||||
INCLUDE_DIRECTORIES(
|
||||
include
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${LLVM_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(dcc_SOURCES
|
||||
src/dcc.cpp
|
||||
src/ast.cpp
|
||||
@ -60,4 +68,5 @@ set(dcc_HEADERS
|
||||
include/BasicBlock.h
|
||||
)
|
||||
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
||||
TARGET_LINK_LIBRARIES(dcc_original ${REQ_LLVM_LIBRARIES})
|
||||
|
||||
|
||||
@ -2,12 +2,16 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <llvm/ADT/ilist.h>
|
||||
#include <llvm/ADT/ilist_node.h>
|
||||
#include "types.h"
|
||||
#include "graph.h"
|
||||
/* Basic block (BB) node definition */
|
||||
struct Function;
|
||||
class CIcodeRec;
|
||||
struct BB;
|
||||
struct interval;
|
||||
struct ICODE;
|
||||
typedef union
|
||||
{
|
||||
dword ip; /* Out edge icode address */
|
||||
@ -15,13 +19,13 @@ typedef union
|
||||
interval *intPtr; /* Out edge ptr to next interval*/
|
||||
} TYPEADR_TYPE;
|
||||
|
||||
struct BB
|
||||
struct BB : public llvm::ilist_node<BB>
|
||||
{
|
||||
protected:
|
||||
private:
|
||||
BB(const BB&);
|
||||
BB() : nodeType(0),traversed(0),start(0),length(0),
|
||||
numHlIcodes(0),flg(0),
|
||||
numInEdges(0),inEdges(0),
|
||||
inEdges(0),
|
||||
numOutEdges(0),edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
||||
inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(0),
|
||||
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
|
||||
@ -29,17 +33,25 @@ protected:
|
||||
{
|
||||
|
||||
}
|
||||
//friend class SymbolTableListTraits<BB, Function>;
|
||||
//Int numInEdges; /* Number of in edges */
|
||||
|
||||
public:
|
||||
Int begin();
|
||||
Int end();
|
||||
Int rbegin();
|
||||
Int rend();
|
||||
ICODE &front();
|
||||
ICODE &back();
|
||||
size_t size();
|
||||
byte nodeType; /* Type of node */
|
||||
Int traversed; /* Boolean: traversed yet? */
|
||||
int traversed; /* Boolean: traversed yet? */
|
||||
Int start; /* First instruction offset */
|
||||
Int length; /* No. of instructions this BB */
|
||||
Int numHlIcodes; /* No. of high-level icodes */
|
||||
flags32 flg; /* BB flags */
|
||||
|
||||
|
||||
/* In edges and out edges */
|
||||
Int numInEdges; /* Number of in edges */
|
||||
std::vector<BB *> inEdges; // does not own held pointers
|
||||
|
||||
Int numOutEdges; /* Number of out edges */
|
||||
@ -81,8 +93,17 @@ public:
|
||||
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, byte 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);
|
||||
void displayDfs();
|
||||
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);
|
||||
void displayDfs();
|
||||
void display();
|
||||
/// getParent - Return the enclosing method, or null if none
|
||||
///
|
||||
const Function *getParent() const { return Parent; }
|
||||
Function *getParent() { return Parent; }
|
||||
void writeBB(ICODE *hli, Int lev, Function *pProc, Int *numLoc);
|
||||
private:
|
||||
Function *Parent;
|
||||
|
||||
};
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
#include <llvm/ADT/ilist.h>
|
||||
#include <llvm/ADT/ilist_node.h>
|
||||
#include "BasicBlock.h"
|
||||
#include "types.h"
|
||||
#include "ast.h"
|
||||
#include "icode.h"
|
||||
@ -9,8 +12,44 @@
|
||||
#include "StackFrame.h"
|
||||
/* PROCEDURE NODE */
|
||||
struct CALL_GRAPH;
|
||||
struct Function
|
||||
namespace llvm
|
||||
{
|
||||
// Traits for intrusive list of basic blocks...
|
||||
template<>
|
||||
struct ilist_traits<BB> : public ilist_default_traits<BB>
|
||||
{
|
||||
|
||||
// createSentinel is used to get hold of the node that marks the end of the
|
||||
// list... (same trick used here as in ilist_traits<Instruction>)
|
||||
BB *createSentinel() const {
|
||||
return static_cast<BB*>(&Sentinel);
|
||||
}
|
||||
static void destroySentinel(BB*) {}
|
||||
|
||||
BB *provideInitialHead() const { return createSentinel(); }
|
||||
BB *ensureHead(BB*) const { return createSentinel(); }
|
||||
static void noteHead(BB*, BB*) {}
|
||||
|
||||
//static ValueSymbolTable *getSymTab(Function *ItemParent);
|
||||
private:
|
||||
mutable ilist_half_node<BB> Sentinel;
|
||||
};
|
||||
}
|
||||
struct FunctionType
|
||||
{
|
||||
bool m_vararg;
|
||||
bool isVarArg() const {return m_vararg;}
|
||||
};
|
||||
struct Function : public llvm::ilist_node<Function>
|
||||
{
|
||||
typedef llvm::iplist<BB> BasicBlockListType;
|
||||
// BasicBlock iterators...
|
||||
typedef BasicBlockListType::iterator iterator;
|
||||
typedef BasicBlockListType::const_iterator const_iterator;
|
||||
private:
|
||||
BasicBlockListType BasicBlocks; ///< The basic blocks
|
||||
|
||||
public:
|
||||
dword procEntry; /* label number */
|
||||
char name[SYMLEN]; /* Meaningful name for this proc */
|
||||
STATE state; /* Entry state */
|
||||
@ -36,15 +75,16 @@ struct Function
|
||||
dword liveOut; /* Registers that may be used in successors */
|
||||
boolT liveAnal; /* Procedure has been analysed already */
|
||||
|
||||
/* Double-linked list */
|
||||
// Function *next;
|
||||
// Function *prev;
|
||||
public:
|
||||
Function() : procEntry(0),depth(0),flg(0),cbParam(0),cfg(0),dfsLast(0),numBBs(0),
|
||||
Function(void *ty=0) : procEntry(0),depth(0),flg(0),cbParam(0),cfg(0),dfsLast(0),numBBs(0),
|
||||
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
|
||||
{
|
||||
memset(name,0,SYMLEN);
|
||||
}
|
||||
public:
|
||||
static Function *Create(void *ty=0,int Linkage=0,const std::string &nm="",void *module=0)
|
||||
{
|
||||
return new Function(ty);
|
||||
}
|
||||
void compoundCond();
|
||||
void writeProcComments();
|
||||
void lowLevelAnalysis();
|
||||
@ -66,7 +106,13 @@ public:
|
||||
void codeGen(std::ostream &fs);
|
||||
void displayStats();
|
||||
void mergeFallThrough(BB *pBB);
|
||||
void structIfs();
|
||||
void structLoops(derSeq *derivedG);
|
||||
void buildCFG();
|
||||
void controlFlowAnalysis();
|
||||
void newRegArg(ICODE *picode, ICODE *ticode);
|
||||
protected:
|
||||
void structCases();
|
||||
void findExps();
|
||||
void genDU1();
|
||||
void elimCondCodes();
|
||||
@ -74,4 +120,6 @@ protected:
|
||||
void findIdioms();
|
||||
void propLong();
|
||||
void genLiveKtes();
|
||||
byte findDerivedSeq (derSeq *derivedGi);
|
||||
bool nextOrderGraph(derSeq *derivedGi);
|
||||
};
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* (C) Cristina Cifuentes, Mike van Emmerik
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <llvm/ADT/ilist.h>
|
||||
#include "types.h"
|
||||
#include "ast.h"
|
||||
#include "icode.h"
|
||||
@ -13,8 +13,11 @@
|
||||
#include "bundle.h"
|
||||
#include "Procedure.h"
|
||||
#include "BasicBlock.h"
|
||||
typedef std::list<Function> lFunction;
|
||||
typedef std::list<Function>::iterator ilFunction;
|
||||
|
||||
typedef llvm::iplist<Function> FunctionListType;
|
||||
typedef FunctionListType lFunction;
|
||||
typedef lFunction::iterator ilFunction;
|
||||
|
||||
|
||||
/* SYMBOL TABLE */
|
||||
struct SYM {
|
||||
@ -50,7 +53,8 @@ public:
|
||||
void insertArc(ilFunction newProc);
|
||||
};
|
||||
#define NUM_PROCS_DELTA 5 /* delta # procs a proc invokes */
|
||||
extern std::list<Function> pProcList;
|
||||
//extern std::list<Function> pProcList;
|
||||
extern FunctionListType pProcList;
|
||||
extern CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
|
||||
extern bundle cCode; /* Output C procedure's declaration and code */
|
||||
|
||||
@ -179,7 +183,6 @@ boolT LibCheck(Function &p); /* chklib.c */
|
||||
|
||||
/* Exported functions from procs.c */
|
||||
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
|
||||
void newRegArg (Function *, ICODE *, ICODE *);
|
||||
boolT newStkArg (ICODE *, COND_EXPR *, llIcode, Function *);
|
||||
void allocStkArgs (ICODE *, Int);
|
||||
void placeStkArg (ICODE *, COND_EXPR *, Int);
|
||||
@ -190,7 +193,6 @@ void removeRegFromLong (byte, LOCAL_ID *, COND_EXPR *);
|
||||
std::string walkCondExpr (const COND_EXPR *exp, Function * pProc, Int *);
|
||||
Int hlTypeSize (const COND_EXPR *, Function *);
|
||||
hlType expType (const COND_EXPR *, Function *);
|
||||
void copyDU (ICODE *, const ICODE *, operDu, operDu);
|
||||
boolT insertSubTreeReg (COND_EXPR *, COND_EXPR **, byte, LOCAL_ID *);
|
||||
boolT insertSubTreeLongReg (COND_EXPR *, COND_EXPR **, Int);
|
||||
//COND_EXPR *concatExps (SEQ_COND_EXPR *, COND_EXPR *, condNodeType);
|
||||
@ -202,7 +204,6 @@ Int numElemExpStk();
|
||||
boolT emptyExpStk();
|
||||
|
||||
/* Exported functions from hlicode.c */
|
||||
boolT removeDefRegi (byte, ICODE *, Int, LOCAL_ID *);
|
||||
std::string writeCall (Function *, STKFRAME *, Function *, Int *);
|
||||
char *write1HlIcode (HLTYPE, Function *, Int *);
|
||||
char *writeJcond (HLTYPE, Function *, Int *);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include <vector>
|
||||
struct Function;
|
||||
/* Types of basic block nodes */
|
||||
/* Real basic blocks: type defined according to their out-edges */
|
||||
enum eBBKind
|
||||
@ -88,7 +89,7 @@ struct derSeq_Entry
|
||||
}
|
||||
~derSeq_Entry();
|
||||
public:
|
||||
void findIntervals();
|
||||
void findIntervals(Function *c);
|
||||
};
|
||||
class derSeq : public std::list<derSeq_Entry>
|
||||
{
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include <vector>
|
||||
#include "Enums.h"
|
||||
//enum condId;
|
||||
|
||||
struct LOCAL_ID;
|
||||
/* LOW_LEVEL icode flags */
|
||||
enum eLLFlags
|
||||
{
|
||||
@ -45,16 +45,19 @@ enum eLLFlags
|
||||
|
||||
/* Parser flags */
|
||||
#define TO_REG 0x000100 /* rm is source */
|
||||
#define S 0x000200 /* sign extend */
|
||||
#define S_EXT 0x000200 /* sign extend */
|
||||
#define OP386 0x000400 /* 386 op-code */
|
||||
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
||||
#define ICODEMASK 0xFF00FF /* Masks off parser flags */
|
||||
|
||||
/* LOW_LEVEL icode, DU flag bits */
|
||||
#define Cf 1
|
||||
#define Sf 2
|
||||
#define Zf 4
|
||||
#define Df 8
|
||||
enum eDuFlags
|
||||
{
|
||||
Cf=1,
|
||||
Sf=2,
|
||||
Zf=4,
|
||||
Df=8
|
||||
};
|
||||
|
||||
/* Machine registers */
|
||||
#define rAX 1 /* These are numbered relative to real 8086 */
|
||||
@ -227,7 +230,7 @@ typedef enum {
|
||||
HLI_RET, /* Return from procedure */
|
||||
/* pseudo high-level icodes */
|
||||
HLI_POP, /* Pop expression */
|
||||
HLI_PUSH, /* Push expression */
|
||||
HLI_PUSH /* Push expression */
|
||||
} hlIcode;
|
||||
|
||||
/* Def/use of flags - low 4 bits represent flags */
|
||||
@ -250,13 +253,6 @@ struct DU_ICODE
|
||||
#define MAX_REGS_DEF 2 /* 2 regs def'd for long-reg vars */
|
||||
#define MAX_USES 5
|
||||
|
||||
struct DU1
|
||||
{
|
||||
Int numRegsDef; /* # registers defined by this inst */
|
||||
byte regi[MAX_REGS_DEF]; /* registers defined by this inst */
|
||||
Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
|
||||
};
|
||||
|
||||
|
||||
/* LOW_LEVEL icode operand record */
|
||||
struct ICODEMEM
|
||||
@ -312,6 +308,12 @@ typedef struct
|
||||
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */
|
||||
struct ICODE
|
||||
{
|
||||
struct DU1
|
||||
{
|
||||
Int numRegsDef; /* # registers defined by this inst */
|
||||
byte regi[MAX_REGS_DEF]; /* registers defined by this inst */
|
||||
Int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
|
||||
};
|
||||
icodeType type; /* Icode type */
|
||||
boolT invalid; /* Has no HIGH_LEVEL equivalent */
|
||||
BB *inBB; /* BB to which this icode belongs */
|
||||
@ -323,6 +325,13 @@ struct ICODE
|
||||
HLTYPE hl; /* For HIGH_LEVEL icodes */
|
||||
};
|
||||
IC ic;/* intermediate code */
|
||||
int loc_ip; // used by CICodeRec to number ICODEs
|
||||
|
||||
void SetLlFlag(dword flag) {ic.ll.flg |= flag;}
|
||||
dword GetLlFlag() {return ic.ll.flg;}
|
||||
bool isLlFlag(dword flg) {return (ic.ll.flg&flg)==flg;}
|
||||
llIcode GetLlOpcode() const { return ic.ll.opcode; }
|
||||
|
||||
void writeIntComment(char *s);
|
||||
void setRegDU(byte regi, operDu du_in);
|
||||
void invalidate();
|
||||
@ -333,7 +342,10 @@ struct ICODE
|
||||
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs); // set this icode to be an assign
|
||||
void setUnary(hlIcode op, COND_EXPR *exp);
|
||||
void setJCond(COND_EXPR *cexp);
|
||||
int loc_ip; // used by CICodeRec to number ICODEs
|
||||
void emitGotoLabel(Int indLevel);
|
||||
void copyDU(const ICODE &duIcode, operDu _du, operDu duDu);
|
||||
public:
|
||||
boolT removeDefRegi(byte regi, Int thisDefIdx, LOCAL_ID *locId);
|
||||
};
|
||||
|
||||
// This is the icode array object.
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "icode.h"
|
||||
/* Type definition */
|
||||
struct IDX_ARRAY : public std::vector<int>
|
||||
{
|
||||
@ -111,7 +112,9 @@ struct LOCAL_ID
|
||||
std::vector<ID> id_arr;
|
||||
public:
|
||||
LOCAL_ID()
|
||||
{}
|
||||
{
|
||||
id_arr.reserve(256);
|
||||
}
|
||||
Int newByteWordReg(hlType t, byte regi);
|
||||
Int newByteWordStk(hlType t, Int off, byte regOff);
|
||||
Int newIntIdx(int16 seg, int16 off, byte regi, Int ix, hlType t);
|
||||
|
||||
@ -47,7 +47,7 @@ typedef unsigned char boolT; /* 8 bits */
|
||||
|
||||
/* Macro reads a LH word from the image regardless of host convention */
|
||||
/* Returns a signed quantity, e.g. C000 is read into an Int as FFFFC000 */
|
||||
#define LHS(p) (((byte *)(p))[0] + (((char *)(p))[1] << 8))
|
||||
#define LH_SIGNED(p) (((byte *)(p))[0] + (((char *)(p))[1] << 8))
|
||||
|
||||
/* Macro tests bit b for type t in prog.map */
|
||||
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
|
||||
|
||||
@ -1,9 +1,16 @@
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
#include "BasicBlock.h"
|
||||
#include "Procedure.h"
|
||||
#include "dcc.h"
|
||||
BB *BB::Create(void *ctx, const std::string &s, Function *parent, BB *insertBefore)
|
||||
using namespace std;
|
||||
extern char *indent (Int indLevel);
|
||||
BB *BB::Create(void *ctx, const string &s, Function *parent, BB *insertBefore)
|
||||
{
|
||||
return new BB;
|
||||
BB *pnewBB = new BB;
|
||||
pnewBB->Parent = parent;
|
||||
return pnewBB;
|
||||
}
|
||||
|
||||
BB *BB::Create(Int start, Int ip, byte nodeType, Int numOutEdges, Function *parent)
|
||||
@ -31,8 +38,334 @@ BB *BB::Create(Int start, Int ip, byte nodeType, Int numOutEdges, Function *pare
|
||||
parent->Icode.SetInBB(start, ip, pnewBB);
|
||||
parent->heldBBs.push_back(pnewBB);
|
||||
parent->cfg.push_back(pnewBB);
|
||||
pnewBB->Parent = parent;
|
||||
}
|
||||
if (start != -1) /* Only for code BB's */
|
||||
stats.numBBbef++;
|
||||
return pnewBB;
|
||||
}
|
||||
|
||||
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
|
||||
"loop", "repeat", "interval", "cycleHead",
|
||||
"caseHead", "terminate",
|
||||
"nowhere" };
|
||||
|
||||
static const char *const s_loopType[] = {"noLoop", "while", "repeat", "loop", "for"};
|
||||
|
||||
|
||||
void BB::display()
|
||||
{
|
||||
printf("\nnode type = %s, ", s_nodeType[nodeType]);
|
||||
printf("start = %ld, length = %ld, #out edges = %ld\n",
|
||||
start, length, numOutEdges);
|
||||
|
||||
for (int i = 0; i < numOutEdges; i++)
|
||||
printf(" outEdge[%2d] = %ld\n",i, edges[i].BBptr->start);
|
||||
}
|
||||
/*****************************************************************************
|
||||
* displayDfs - Displays the CFG using a depth first traversal
|
||||
****************************************************************************/
|
||||
void BB::displayDfs()
|
||||
{
|
||||
Int i;
|
||||
assert(this);
|
||||
traversed = DFS_DISP;
|
||||
|
||||
printf("node type = %s, ", s_nodeType[nodeType]);
|
||||
printf("start = %ld, length = %ld, #in-edges = %ld, #out-edges = %ld\n",
|
||||
start, length, inEdges.size(), numOutEdges);
|
||||
printf("dfsFirst = %ld, dfsLast = %ld, immed dom = %ld\n",
|
||||
dfsFirstNum, dfsLastNum,
|
||||
immedDom == MAX ? -1 : immedDom);
|
||||
printf("loopType = %s, loopHead = %ld, latchNode = %ld, follow = %ld\n",
|
||||
s_loopType[loopType],
|
||||
loopHead == MAX ? -1 : loopHead,
|
||||
latchNode == MAX ? -1 : latchNode,
|
||||
loopFollow == MAX ? -1 : loopFollow);
|
||||
printf ("ifFollow = %ld, caseHead = %ld, caseTail = %ld\n",
|
||||
ifFollow == MAX ? -1 : ifFollow,
|
||||
caseHead == MAX ? -1 : caseHead,
|
||||
caseTail == MAX ? -1 : caseTail);
|
||||
|
||||
if (nodeType == INTERVAL_NODE)
|
||||
printf("corresponding interval = %ld\n", correspInt->numInt);
|
||||
else
|
||||
for (i = 0; i < inEdges.size(); i++)
|
||||
printf (" inEdge[%ld] = %ld\n", i, inEdges[i]->begin());
|
||||
|
||||
/* Display out edges information */
|
||||
for (i = 0; i < numOutEdges; i++)
|
||||
if (nodeType == INTERVAL_NODE)
|
||||
printf(" outEdge[%ld] = %ld\n", i,
|
||||
edges[i].BBptr->correspInt->numInt);
|
||||
else
|
||||
printf(" outEdge[%d] = %ld\n", i, edges[i].BBptr->begin());
|
||||
printf("----\n");
|
||||
|
||||
/* Recursive call on successors of current node */
|
||||
for (i = 0; i < numOutEdges; i++)
|
||||
if (edges[i].BBptr->traversed != DFS_DISP)
|
||||
edges[i].BBptr->displayDfs();
|
||||
}
|
||||
/* Recursive procedure that writes the code for the given procedure, pointed
|
||||
* to by pBB.
|
||||
* Parameters: pBB: pointer to the cfg.
|
||||
* Icode: pointer to the Icode array for the cfg graph of the
|
||||
* current procedure.
|
||||
* indLevel: indentation level - used for formatting.
|
||||
* numLoc: last # assigned to local variables */
|
||||
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 */
|
||||
BB * succ, *latch; /* Successor and latching node */
|
||||
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
||||
char *l; /* Pointer to HLI_JCOND expression */
|
||||
boolT emptyThen, /* THEN clause is empty */
|
||||
repCond; /* Repeat condition for while() */
|
||||
|
||||
/* Check if this basic block should be analysed */
|
||||
if ((_ifFollow != UN_INIT) && (this == pProc->dfsLast[_ifFollow]))
|
||||
return;
|
||||
|
||||
if (traversed == DFS_ALPHA)
|
||||
return;
|
||||
traversed = DFS_ALPHA;
|
||||
|
||||
/* Check for start of loop */
|
||||
repCond = FALSE;
|
||||
latch = NULL;
|
||||
_loopType = loopType;
|
||||
if (_loopType)
|
||||
{
|
||||
latch = pProc->dfsLast[this->latchNode];
|
||||
switch (_loopType)
|
||||
{
|
||||
case WHILE_TYPE:
|
||||
picode = &this->back();
|
||||
|
||||
/* Check for error in while condition */
|
||||
if (picode->ic.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(pProc->Icode.GetFirstIcode(), 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)
|
||||
inverseCondOp (&picode->ic.hl.oper.exp);
|
||||
{
|
||||
string e=walkCondExpr (picode->ic.hl.oper.exp, pProc, numLoc);
|
||||
cCode.appendCode( "\n%swhile (%s) {\n", indent(indLevel),e.c_str());
|
||||
}
|
||||
picode->invalidate();
|
||||
break;
|
||||
|
||||
case REPEAT_TYPE:
|
||||
cCode.appendCode( "\n%sdo {\n", indent(indLevel));
|
||||
picode = &latch->back();
|
||||
picode->invalidate();
|
||||
break;
|
||||
|
||||
case ENDLESS_TYPE:
|
||||
cCode.appendCode( "\n%sfor (;;) {\n", indent(indLevel));
|
||||
}
|
||||
stats.numHLIcode += 1;
|
||||
indLevel++;
|
||||
}
|
||||
|
||||
/* Write the code for this basic block */
|
||||
if (repCond == FALSE)
|
||||
writeBB (pProc->Icode.GetFirstIcode(), indLevel, pProc, numLoc);
|
||||
|
||||
/* Check for end of path */
|
||||
_nodeType = nodeType;
|
||||
if (_nodeType == RETURN_NODE || _nodeType == TERMINATE_NODE ||
|
||||
_nodeType == NOWHERE_NODE || (dfsLastNum == latchNode))
|
||||
return;
|
||||
|
||||
/* Check type of loop/node and process code */
|
||||
if (_loopType) /* there is a loop */
|
||||
{
|
||||
assert(latch);
|
||||
if (this != latch) /* loop is over several bbs */
|
||||
{
|
||||
if (_loopType == WHILE_TYPE)
|
||||
{
|
||||
succ = edges[THEN].BBptr;
|
||||
if (succ->dfsLastNum == loopFollow)
|
||||
succ = edges[ELSE].BBptr;
|
||||
}
|
||||
else
|
||||
succ = edges[0].BBptr;
|
||||
if (succ->traversed != DFS_ALPHA)
|
||||
succ->writeCode (indLevel, pProc, numLoc, latch->dfsLastNum,_ifFollow);
|
||||
else /* has been traversed so we need a goto */
|
||||
succ->front().emitGotoLabel (indLevel);
|
||||
}
|
||||
|
||||
/* Loop epilogue: generate the loop trailer */
|
||||
indLevel--;
|
||||
if (_loopType == WHILE_TYPE)
|
||||
{
|
||||
/* Check if there is need to repeat other statements involved
|
||||
* in while condition, then, emit the loop trailer */
|
||||
if (repCond)
|
||||
writeBB (pProc->Icode.GetFirstIcode(), indLevel+1, pProc, numLoc);
|
||||
cCode.appendCode( "%s} /* end of while */\n",indent(indLevel));
|
||||
}
|
||||
else if (_loopType == ENDLESS_TYPE)
|
||||
cCode.appendCode( "%s} /* end of loop */\n",indent(indLevel));
|
||||
else if (_loopType == REPEAT_TYPE)
|
||||
{
|
||||
if (picode->ic.hl.opcode != HLI_JCOND)
|
||||
reportError (REPEAT_FAIL);
|
||||
{
|
||||
string e=walkCondExpr (picode->ic.hl.oper.exp, pProc, numLoc);
|
||||
cCode.appendCode( "%s} while (%s);\n", indent(indLevel),e.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/* Recurse on the loop follow */
|
||||
if (loopFollow != MAX)
|
||||
{
|
||||
succ = pProc->dfsLast[loopFollow];
|
||||
if (succ->traversed != DFS_ALPHA)
|
||||
succ->writeCode (indLevel, pProc, numLoc, latchNode, _ifFollow);
|
||||
else /* has been traversed so we need a goto */
|
||||
succ->front().emitGotoLabel (indLevel);
|
||||
}
|
||||
}
|
||||
|
||||
else /* no loop, process nodeType of the graph */
|
||||
{
|
||||
if (_nodeType == TWO_BRANCH) /* if-then[-else] */
|
||||
{
|
||||
stats.numHLIcode++;
|
||||
indLevel++;
|
||||
emptyThen = FALSE;
|
||||
|
||||
if (ifFollow != MAX) /* there is a follow */
|
||||
{
|
||||
/* process the THEN part */
|
||||
follow = ifFollow;
|
||||
succ = edges[THEN].BBptr;
|
||||
if (succ->traversed != DFS_ALPHA) /* not visited */
|
||||
{
|
||||
if (succ->dfsLastNum != follow) /* THEN part */
|
||||
{
|
||||
l = writeJcond ( back().ic.hl, pProc, numLoc);
|
||||
cCode.appendCode( "\n%s%s", indent(indLevel-1), l);
|
||||
succ->writeCode (indLevel, pProc, numLoc, latchNode,follow);
|
||||
}
|
||||
else /* empty THEN part => negate ELSE part */
|
||||
{
|
||||
l = writeJcondInv ( back().ic.hl, pProc, numLoc);
|
||||
cCode.appendCode( "\n%s%s", indent(indLevel-1), l);
|
||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, latchNode, follow);
|
||||
emptyThen = TRUE;
|
||||
}
|
||||
}
|
||||
else /* already visited => emit label */
|
||||
succ->front().emitGotoLabel(indLevel);
|
||||
|
||||
/* process the ELSE part */
|
||||
succ = edges[ELSE].BBptr;
|
||||
if (succ->traversed != DFS_ALPHA) /* not visited */
|
||||
{
|
||||
if (succ->dfsLastNum != follow) /* ELSE part */
|
||||
{
|
||||
cCode.appendCode( "%s}\n%selse {\n",
|
||||
indent(indLevel-1), indent(indLevel - 1));
|
||||
succ->writeCode (indLevel, pProc, numLoc, latchNode, follow);
|
||||
}
|
||||
/* else (empty ELSE part) */
|
||||
}
|
||||
else if (! emptyThen) /* already visited => emit label */
|
||||
{
|
||||
cCode.appendCode( "%s}\n%selse {\n",
|
||||
indent(indLevel-1), indent(indLevel - 1));
|
||||
succ->front().emitGotoLabel (indLevel);
|
||||
}
|
||||
cCode.appendCode( "%s}\n", indent(--indLevel));
|
||||
|
||||
/* Continue with the follow */
|
||||
succ = pProc->dfsLast[follow];
|
||||
if (succ->traversed != DFS_ALPHA)
|
||||
succ->writeCode (indLevel, pProc, numLoc, latchNode,_ifFollow);
|
||||
}
|
||||
else /* no follow => if..then..else */
|
||||
{
|
||||
l = writeJcond (
|
||||
back().ic.hl, pProc, numLoc);
|
||||
cCode.appendCode( "%s%s", indent(indLevel-1), l);
|
||||
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, latchNode, _ifFollow);
|
||||
cCode.appendCode( "%s}\n%selse {\n", indent(indLevel-1), indent(indLevel - 1));
|
||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, latchNode, _ifFollow);
|
||||
cCode.appendCode( "%s}\n", indent(--indLevel));
|
||||
}
|
||||
}
|
||||
|
||||
else /* fall, call, 1w */
|
||||
{
|
||||
succ = edges[0].BBptr; /* fall-through edge */
|
||||
if (succ->traversed != DFS_ALPHA)
|
||||
succ->writeCode (indLevel, pProc,numLoc, latchNode,_ifFollow);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Writes the code for the current basic block.
|
||||
* Args: pBB: pointer to the current basic block.
|
||||
* Icode: pointer to the array of icodes for current procedure.
|
||||
* lev: indentation level - used for formatting. */
|
||||
void BB::writeBB(ICODE * hli, Int lev, Function * pProc, Int *numLoc)
|
||||
{
|
||||
Int i, last;
|
||||
char *line; /* Pointer to the HIGH-LEVEL line */
|
||||
|
||||
/* Save the index into the code table in case there is a later goto
|
||||
* into this instruction (first instruction of the BB) */
|
||||
hli[start].codeIdx = nextBundleIdx (&cCode.code);
|
||||
|
||||
/* Generate code for each hlicode that is not a HLI_JCOND */
|
||||
for (i = start, last = i + length; i < last; i++)
|
||||
if ((hli[i].type == HIGH_LEVEL) && (hli[i].invalid == FALSE))
|
||||
{
|
||||
line = write1HlIcode (hli[i].ic.hl, pProc, numLoc);
|
||||
if (line[0] != '\0')
|
||||
{
|
||||
cCode.appendCode( "%s%s", indent(lev), line);
|
||||
stats.numHLIcode++;
|
||||
}
|
||||
if (option.verbose)
|
||||
hli[i].writeDU(i);
|
||||
}
|
||||
}
|
||||
int BB::begin()
|
||||
{
|
||||
return start;
|
||||
}
|
||||
int BB::rbegin()
|
||||
{
|
||||
return start+length-1;
|
||||
}
|
||||
int BB::end()
|
||||
{
|
||||
return start+length;
|
||||
}
|
||||
ICODE &BB::back()
|
||||
{
|
||||
return Parent->Icode[rbegin()];
|
||||
}
|
||||
|
||||
ICODE &BB::front()
|
||||
{
|
||||
return Parent->Icode[start];
|
||||
}
|
||||
|
||||
6
src/Procedure.cpp
Normal file
6
src/Procedure.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "Procedure.h"
|
||||
|
||||
FunctionType *Function::getFunctionType() const
|
||||
{
|
||||
return &m_type;
|
||||
}
|
||||
17
src/ast.cpp
17
src/ast.cpp
@ -72,30 +72,31 @@ void ICODE::setRegDU (byte regi, operDu du_in)
|
||||
|
||||
|
||||
/* Copies the def, use, or def and use fields of duIcode into pIcode */
|
||||
void copyDU (ICODE *pIcode, const ICODE *duIcode, operDu du, operDu duDu)
|
||||
void ICODE::copyDU(const ICODE &duIcode, operDu _du, operDu duDu)
|
||||
{
|
||||
// printf("%s %d,%d from %d to %d\n",__FUNCTION__,int(du),int(duDu),duIcode->ic.ll.opcode,pIcode->ic.ll.opcode);
|
||||
switch (du) {
|
||||
switch (_du)
|
||||
{
|
||||
case eDEF:
|
||||
if (duDu == eDEF)
|
||||
pIcode->du.def=duIcode->du.def;
|
||||
du.def=duIcode.du.def;
|
||||
else
|
||||
pIcode->du.def=duIcode->du.use;
|
||||
du.def=duIcode.du.use;
|
||||
break;
|
||||
case eUSE:
|
||||
if (duDu == eDEF)
|
||||
pIcode->du.use=duIcode->du.def;
|
||||
du.use=duIcode.du.def;
|
||||
else
|
||||
pIcode->du.use =duIcode->du.use;
|
||||
du.use =duIcode.du.use;
|
||||
break;
|
||||
case USE_DEF:
|
||||
pIcode->du = duIcode->du;
|
||||
du = duIcode.du;
|
||||
break;
|
||||
case NONE:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
printf("%s end: %x,%x\n",__FUNCTION__,pIcode->du.def,pIcode->du.use);
|
||||
printf("%s end: %x,%x\n",__FUNCTION__,du.def,du.use);
|
||||
}
|
||||
|
||||
|
||||
|
||||
287
src/backend.cpp
287
src/backend.cpp
@ -22,18 +22,16 @@ static char indentBuf[indSize] =
|
||||
|
||||
|
||||
/* Indentation according to the depth of the statement */
|
||||
static char *indent (Int indLevel)
|
||||
char *indent (Int indLevel)
|
||||
{
|
||||
|
||||
|
||||
return (&indentBuf[indSize-(indLevel*4)-1]);
|
||||
}
|
||||
|
||||
|
||||
static Int getNextLabel()
|
||||
/* Returns a unique index to the next label */
|
||||
{ static Int labelIdx = 1; /* index of the next label */
|
||||
|
||||
Int getNextLabel()
|
||||
{
|
||||
static Int labelIdx = 1; /* index of the next label */
|
||||
return (labelIdx++);
|
||||
}
|
||||
|
||||
@ -206,36 +204,14 @@ static void writeBitVector (dword regi)
|
||||
}
|
||||
|
||||
|
||||
/* Checks the given icode to determine whether it has a label associated
|
||||
* to it. If so, a goto is emitted to this label; otherwise, a new label
|
||||
* is created and a goto is also emitted.
|
||||
* Note: this procedure is to be used when the label is to be backpatched
|
||||
* onto code in cCode.code */
|
||||
static void emitGotoLabel (ICODE * pt, Int indLevel)
|
||||
{
|
||||
if (! (pt->ic.ll.flg & HLL_LABEL)) /* node hasn't got a lab */
|
||||
{
|
||||
/* Generate new label */
|
||||
pt->ic.ll.hllLabNum = getNextLabel();
|
||||
pt->ic.ll.flg |= HLL_LABEL;
|
||||
|
||||
/* Node has been traversed already, so backpatch this label into
|
||||
* the code */
|
||||
addLabelBundle (cCode.code, pt->codeIdx, pt->ic.ll.hllLabNum);
|
||||
}
|
||||
cCode.appendCode( "%sgoto L%ld;\n", indent(indLevel),
|
||||
pt->ic.ll.hllLabNum);
|
||||
stats.numHLIcode++;
|
||||
}
|
||||
|
||||
|
||||
// Note: Not currently called!
|
||||
static void emitFwdGotoLabel (ICODE * pt, Int indLevel)
|
||||
/* Checks the given icode to determine whether it has a label associated
|
||||
* to it. If so, a goto is emitted to this label; otherwise, a new label
|
||||
* is created and a goto is also emitted.
|
||||
* Note: this procedure is to be used when the label is to be forward on
|
||||
* the code; that is, the target code has not been traversed yet. */
|
||||
static void emitFwdGotoLabel (ICODE * pt, Int indLevel)
|
||||
{
|
||||
if (! (pt->ic.ll.flg & HLL_LABEL)) /* node hasn't got a lab */
|
||||
{
|
||||
@ -248,254 +224,6 @@ static void emitFwdGotoLabel (ICODE * pt, Int indLevel)
|
||||
}
|
||||
|
||||
|
||||
/* Writes the code for the current basic block.
|
||||
* Args: pBB: pointer to the current basic block.
|
||||
* Icode: pointer to the array of icodes for current procedure.
|
||||
* lev: indentation level - used for formatting. */
|
||||
static void writeBB (const BB * const pBB, ICODE * hli, Int lev, Function * pProc, Int *numLoc)
|
||||
{ Int i, last;
|
||||
char *line; /* Pointer to the HIGH-LEVEL line */
|
||||
|
||||
/* Save the index into the code table in case there is a later goto
|
||||
* into this instruction (first instruction of the BB) */
|
||||
hli[pBB->start].codeIdx = nextBundleIdx (&cCode.code);
|
||||
|
||||
/* Generate code for each hlicode that is not a HLI_JCOND */
|
||||
for (i = pBB->start, last = i + pBB->length; i < last; i++)
|
||||
if ((hli[i].type == HIGH_LEVEL) && (hli[i].invalid == FALSE))
|
||||
{
|
||||
line = write1HlIcode (hli[i].ic.hl, pProc, numLoc);
|
||||
if (line[0] != '\0')
|
||||
{
|
||||
cCode.appendCode( "%s%s", indent(lev), line);
|
||||
stats.numHLIcode++;
|
||||
}
|
||||
if (option.verbose)
|
||||
hli[i].writeDU(i);
|
||||
}
|
||||
//if (hli[i].invalid)
|
||||
//printf("Invalid icode: %d!\n", hli[i].invalid);
|
||||
}
|
||||
|
||||
|
||||
/* Recursive procedure that writes the code for the given procedure, pointed
|
||||
* to by pBB.
|
||||
* Parameters: pBB: pointer to the cfg.
|
||||
* Icode: pointer to the Icode array for the cfg graph of the
|
||||
* current procedure.
|
||||
* indLevel: indentation level - used for formatting.
|
||||
* numLoc: last # assigned to local variables */
|
||||
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 */
|
||||
BB * succ, *latch; /* Successor and latching node */
|
||||
ICODE * picode; /* Pointer to HLI_JCOND instruction */
|
||||
char *l; /* Pointer to HLI_JCOND expression */
|
||||
boolT emptyThen, /* THEN clause is empty */
|
||||
repCond; /* Repeat condition for while() */
|
||||
|
||||
/* Check if this basic block should be analysed */
|
||||
if ((_ifFollow != UN_INIT) && (this == pProc->dfsLast[_ifFollow]))
|
||||
return;
|
||||
|
||||
if (traversed == DFS_ALPHA)
|
||||
return;
|
||||
traversed = DFS_ALPHA;
|
||||
|
||||
/* Check for start of loop */
|
||||
repCond = FALSE;
|
||||
latch = NULL;
|
||||
_loopType = loopType;
|
||||
if (_loopType)
|
||||
{
|
||||
latch = pProc->dfsLast[this->latchNode];
|
||||
switch (_loopType)
|
||||
{
|
||||
case WHILE_TYPE:
|
||||
picode = pProc->Icode.GetIcode(start + length - 1);
|
||||
|
||||
/* Check for error in while condition */
|
||||
if (picode->ic.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(this, pProc->Icode.GetFirstIcode(), 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)
|
||||
inverseCondOp (&picode->ic.hl.oper.exp);
|
||||
{
|
||||
std::string e=walkCondExpr (picode->ic.hl.oper.exp, pProc, numLoc);
|
||||
cCode.appendCode( "\n%swhile (%s) {\n", indent(indLevel),e.c_str());
|
||||
}
|
||||
picode->invalidate();
|
||||
break;
|
||||
|
||||
case REPEAT_TYPE:
|
||||
cCode.appendCode( "\n%sdo {\n", indent(indLevel));
|
||||
picode = pProc->Icode.GetIcode(latch->start+latch->length-1);
|
||||
picode->invalidate();
|
||||
break;
|
||||
|
||||
case ENDLESS_TYPE:
|
||||
cCode.appendCode( "\n%sfor (;;) {\n", indent(indLevel));
|
||||
}
|
||||
stats.numHLIcode += 1;
|
||||
indLevel++;
|
||||
}
|
||||
|
||||
/* Write the code for this basic block */
|
||||
if (repCond == FALSE)
|
||||
writeBB (this, pProc->Icode.GetFirstIcode(), indLevel, pProc, numLoc);
|
||||
|
||||
/* Check for end of path */
|
||||
_nodeType = nodeType;
|
||||
if (_nodeType == RETURN_NODE || _nodeType == TERMINATE_NODE ||
|
||||
_nodeType == NOWHERE_NODE || (dfsLastNum == latchNode))
|
||||
return;
|
||||
|
||||
/* Check type of loop/node and process code */
|
||||
if (_loopType) /* there is a loop */
|
||||
{
|
||||
assert(latch);
|
||||
if (this != latch) /* loop is over several bbs */
|
||||
{
|
||||
if (_loopType == WHILE_TYPE)
|
||||
{
|
||||
succ = edges[THEN].BBptr;
|
||||
if (succ->dfsLastNum == loopFollow)
|
||||
succ = edges[ELSE].BBptr;
|
||||
}
|
||||
else
|
||||
succ = edges[0].BBptr;
|
||||
if (succ->traversed != DFS_ALPHA)
|
||||
succ->writeCode (indLevel, pProc, numLoc, latch->dfsLastNum,_ifFollow);
|
||||
else /* has been traversed so we need a goto */
|
||||
emitGotoLabel (pProc->Icode.GetIcode(succ->start), indLevel);
|
||||
}
|
||||
|
||||
/* Loop epilogue: generate the loop trailer */
|
||||
indLevel--;
|
||||
if (_loopType == WHILE_TYPE)
|
||||
{
|
||||
/* Check if there is need to repeat other statements involved
|
||||
* in while condition, then, emit the loop trailer */
|
||||
if (repCond)
|
||||
writeBB (this, pProc->Icode.GetFirstIcode(), indLevel+1, pProc, numLoc);
|
||||
cCode.appendCode( "%s} /* end of while */\n",indent(indLevel));
|
||||
}
|
||||
else if (_loopType == ENDLESS_TYPE)
|
||||
cCode.appendCode( "%s} /* end of loop */\n",indent(indLevel));
|
||||
else if (_loopType == REPEAT_TYPE)
|
||||
{
|
||||
if (picode->ic.hl.opcode != HLI_JCOND)
|
||||
reportError (REPEAT_FAIL);
|
||||
{
|
||||
string e=walkCondExpr (picode->ic.hl.oper.exp, pProc, numLoc);
|
||||
cCode.appendCode( "%s} while (%s);\n", indent(indLevel),e.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/* Recurse on the loop follow */
|
||||
if (loopFollow != MAX)
|
||||
{
|
||||
succ = pProc->dfsLast[loopFollow];
|
||||
if (succ->traversed != DFS_ALPHA)
|
||||
succ->writeCode (indLevel, pProc, numLoc, latchNode, _ifFollow);
|
||||
else /* has been traversed so we need a goto */
|
||||
emitGotoLabel (pProc->Icode.GetIcode(succ->start), indLevel);
|
||||
}
|
||||
}
|
||||
|
||||
else /* no loop, process nodeType of the graph */
|
||||
{
|
||||
if (_nodeType == TWO_BRANCH) /* if-then[-else] */
|
||||
{
|
||||
stats.numHLIcode++;
|
||||
indLevel++;
|
||||
emptyThen = FALSE;
|
||||
|
||||
if (ifFollow != MAX) /* there is a follow */
|
||||
{
|
||||
/* process the THEN part */
|
||||
follow = ifFollow;
|
||||
succ = edges[THEN].BBptr;
|
||||
if (succ->traversed != DFS_ALPHA) /* not visited */
|
||||
{
|
||||
if (succ->dfsLastNum != follow) /* THEN part */
|
||||
{
|
||||
l = writeJcond ( pProc->Icode.GetIcode(start + length -1)->ic.hl,
|
||||
pProc, numLoc);
|
||||
cCode.appendCode( "\n%s%s", indent(indLevel-1), l);
|
||||
succ->writeCode (indLevel, pProc, numLoc, latchNode,follow);
|
||||
}
|
||||
else /* empty THEN part => negate ELSE part */
|
||||
{
|
||||
l = writeJcondInv ( pProc->Icode.GetIcode(start + length -1)->ic.hl,
|
||||
pProc, numLoc);
|
||||
cCode.appendCode( "\n%s%s", indent(indLevel-1), l);
|
||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, latchNode, follow);
|
||||
emptyThen = TRUE;
|
||||
}
|
||||
}
|
||||
else /* already visited => emit label */
|
||||
emitGotoLabel (pProc->Icode.GetIcode(succ->start), indLevel);
|
||||
|
||||
/* process the ELSE part */
|
||||
succ = edges[ELSE].BBptr;
|
||||
if (succ->traversed != DFS_ALPHA) /* not visited */
|
||||
{
|
||||
if (succ->dfsLastNum != follow) /* ELSE part */
|
||||
{
|
||||
cCode.appendCode( "%s}\n%selse {\n",
|
||||
indent(indLevel-1), indent(indLevel - 1));
|
||||
succ->writeCode (indLevel, pProc, numLoc, latchNode, follow);
|
||||
}
|
||||
/* else (empty ELSE part) */
|
||||
}
|
||||
else if (! emptyThen) /* already visited => emit label */
|
||||
{
|
||||
cCode.appendCode( "%s}\n%selse {\n",
|
||||
indent(indLevel-1), indent(indLevel - 1));
|
||||
emitGotoLabel (pProc->Icode.GetIcode(succ->start), indLevel);
|
||||
}
|
||||
cCode.appendCode( "%s}\n", indent(--indLevel));
|
||||
|
||||
/* Continue with the follow */
|
||||
succ = pProc->dfsLast[follow];
|
||||
if (succ->traversed != DFS_ALPHA)
|
||||
succ->writeCode (indLevel, pProc, numLoc, latchNode,_ifFollow);
|
||||
}
|
||||
else /* no follow => if..then..else */
|
||||
{
|
||||
l = writeJcond (
|
||||
pProc->Icode.GetIcode(start + length -1)->ic.hl, pProc, numLoc);
|
||||
cCode.appendCode( "%s%s", indent(indLevel-1), l);
|
||||
edges[THEN].BBptr->writeCode (indLevel, pProc, numLoc, latchNode, _ifFollow);
|
||||
cCode.appendCode( "%s}\n%selse {\n", indent(indLevel-1), indent(indLevel - 1));
|
||||
edges[ELSE].BBptr->writeCode (indLevel, pProc, numLoc, latchNode, _ifFollow);
|
||||
cCode.appendCode( "%s}\n", indent(--indLevel));
|
||||
}
|
||||
}
|
||||
|
||||
else /* fall, call, 1w */
|
||||
{
|
||||
succ = edges[0].BBptr; /* fall-through edge */
|
||||
if (succ->traversed != DFS_ALPHA)
|
||||
succ->writeCode (indLevel, pProc,numLoc, latchNode,_ifFollow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Writes the procedure's declaration (including arguments), local variables,
|
||||
* and invokes the procedure that writes the code of the given record *hli */
|
||||
void Function::codeGen (std::ostream &fs)
|
||||
@ -522,7 +250,7 @@ void Function::codeGen (std::ostream &fs)
|
||||
{
|
||||
sprintf (arg,"%s %s",hlTypes[args.sym[i].type], args.sym[i].name);
|
||||
strcat (buf, arg);
|
||||
if (i < (args.numArgs - 1))
|
||||
if (i < (args.sym.size() - 1))
|
||||
strcat (buf, ", ");
|
||||
}
|
||||
}
|
||||
@ -581,8 +309,7 @@ void Function::codeGen (std::ostream &fs)
|
||||
pBB = dfsLast[i];
|
||||
if (pBB->flg & INVALID_BB) continue; /* skip invalid BBs */
|
||||
printf ("BB %d\n", i);
|
||||
printf (" Start = %d, end = %d\n", pBB->start, pBB->start +
|
||||
pBB->length - 1);
|
||||
printf (" Start = %d, end = %d\n", pBB->begin(), pBB->end());
|
||||
printf (" LiveUse = ");
|
||||
writeBitVector (pBB->liveUse);
|
||||
printf ("\n Def = ");
|
||||
|
||||
@ -505,7 +505,8 @@ boolT LibCheck(Function & pProc)
|
||||
/*** other types are not considered yet ***/
|
||||
}
|
||||
}
|
||||
if (pFunc[i].bVararg) pProc.flg |= PROC_VARARG;
|
||||
if (pFunc[i].bVararg)
|
||||
pProc.flg |= PROC_VARARG;
|
||||
}
|
||||
}
|
||||
else if (i == NIL)
|
||||
@ -707,7 +708,7 @@ void STATE::checkStartup()
|
||||
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainCompact,
|
||||
sizeof(pattMainCompact), &i))
|
||||
{
|
||||
rel = LHS(&prog.Image[i+OFFMAINCOMPACT]);/* This is the rel addr of main */
|
||||
rel = LH_SIGNED(&prog.Image[i+OFFMAINCOMPACT]);/* This is the rel addr of main */
|
||||
prog.offMain = i+OFFMAINCOMPACT+2+rel; /* Save absolute image offset */
|
||||
prog.segMain = prog.initCS;
|
||||
chModel = 'c'; /* Compact model */
|
||||
@ -724,14 +725,14 @@ void STATE::checkStartup()
|
||||
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainSmall,
|
||||
sizeof(pattMainSmall), &i))
|
||||
{
|
||||
rel = LHS(&prog.Image[i+OFFMAINSMALL]); /* This is rel addr of main */
|
||||
rel = LH_SIGNED(&prog.Image[i+OFFMAINSMALL]); /* This is rel addr of main */
|
||||
prog.offMain = i+OFFMAINSMALL+2+rel; /* Save absolute image offset */
|
||||
prog.segMain = prog.initCS;
|
||||
chModel = 's'; /* Small model */
|
||||
}
|
||||
else if (memcmp(&prog.Image[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0)
|
||||
{
|
||||
rel = LHS(&prog.Image[startOff+1]); /* Get the jump offset */
|
||||
rel = LH_SIGNED(&prog.Image[startOff+1]); /* Get the jump offset */
|
||||
prog.offMain = rel+startOff+3; /* Save absolute image offset */
|
||||
prog.offMain += 0x20; /* These first 32 bytes are setting up */
|
||||
prog.segMain = prog.initCS;
|
||||
|
||||
359
src/control.cpp
359
src/control.cpp
@ -35,15 +35,15 @@ static boolT isBackEdge (BB * p,BB * s)
|
||||
if (p->dfsFirstNum >= s->dfsFirstNum)
|
||||
{
|
||||
s->numBackEdges++;
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static Int commonDom (Int currImmDom, Int predImmDom, Function * pProc)
|
||||
/* Finds the common dominator of the current immediate dominator
|
||||
* currImmDom and its predecessor's immediate dominator predImmDom */
|
||||
static Int commonDom (Int currImmDom, Int predImmDom, Function * pProc)
|
||||
{
|
||||
if (currImmDom == NO_DOM)
|
||||
return (predImmDom);
|
||||
@ -82,8 +82,7 @@ void Function::findImmedDom ()
|
||||
BB* inedge=currNode->inEdges[j];
|
||||
predIdx = inedge->dfsLastNum;
|
||||
if (predIdx < currIdx)
|
||||
currNode->immedDom = commonDom (currNode->immedDom,
|
||||
predIdx, this);
|
||||
currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,7 +137,7 @@ static void findEndlessFollow (Function * pProc, nodeList &loopNodes, BB * head)
|
||||
}
|
||||
|
||||
|
||||
//static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes)
|
||||
//static void findNodesInLoop(BB * latchNode,BB * head,PPROC pProc,queue *intNodes)
|
||||
/* Flags nodes that belong to the loop determined by (latchNode, head) and
|
||||
* determines the type of loop. */
|
||||
static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &intNodes)
|
||||
@ -183,7 +182,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
||||
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
||||
else
|
||||
head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
|
||||
pProc->Icode.SetLlFlag(latchNode->start + latchNode->length - 1,JX_LOOP);
|
||||
latchNode->back().SetLlFlag(JX_LOOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -192,7 +191,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
||||
head->loopFollow = head->edges[ELSE].BBptr->dfsLastNum;
|
||||
else
|
||||
head->loopFollow = head->edges[THEN].BBptr->dfsLastNum;
|
||||
pProc->Icode.SetLlFlag(head->start + head->length - 1, JX_LOOP);
|
||||
head->back().SetLlFlag(JX_LOOP);
|
||||
}
|
||||
else /* head = anything besides 2-way, latch = 2-way */
|
||||
{
|
||||
@ -201,8 +200,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
||||
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
||||
else
|
||||
head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
|
||||
pProc->Icode.SetLlFlag(latchNode->start + latchNode->length - 1,
|
||||
JX_LOOP);
|
||||
latchNode->back().SetLlFlag(JX_LOOP);
|
||||
}
|
||||
else /* latch = 1-way */
|
||||
if (latchNode->nodeType == LOOP_NODE)
|
||||
@ -241,7 +239,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
||||
}
|
||||
if (pbb->dfsLastNum > head->dfsLastNum)
|
||||
pProc->dfsLast[head->loopFollow]->loopHead = NO_NODE; /*****/
|
||||
pProc->Icode.SetLlFlag(head->start + head->length - 1, JX_LOOP);
|
||||
head->back().SetLlFlag(JX_LOOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -252,7 +250,6 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
||||
freeList(loopNodes);
|
||||
}
|
||||
|
||||
|
||||
//static void findNodesInInt (queue **intNodes, Int level, interval *Ii)
|
||||
/* Recursive procedure to find nodes that belong to the interval (ie. nodes
|
||||
* from G1). */
|
||||
@ -272,7 +269,7 @@ static void findNodesInInt (queue &intNodes, Int level, interval *Ii)
|
||||
|
||||
|
||||
/* Algorithm for structuring loops */
|
||||
static void structLoops(Function * pProc, derSeq *derivedG)
|
||||
void Function::structLoops(derSeq *derivedG)
|
||||
{
|
||||
interval *Ii;
|
||||
BB * intHead, /* interval header node */
|
||||
@ -305,7 +302,6 @@ static void structLoops(Function * pProc, derSeq *derivedG)
|
||||
findNodesInInt (intNodes, level, Ii);
|
||||
|
||||
/* Find greatest enclosing back edge (if any) */
|
||||
assert(intHead->numInEdges==intHead->inEdges.size());
|
||||
for (i = 0; i < intHead->inEdges.size(); i++)
|
||||
{
|
||||
pred = intHead->inEdges[i];
|
||||
@ -329,7 +325,7 @@ static void structLoops(Function * pProc, derSeq *derivedG)
|
||||
(latchNode->loopHead == NO_NODE))
|
||||
{
|
||||
intHead->latchNode = latchNode->dfsLastNum;
|
||||
findNodesInLoop(latchNode, intHead, pProc, intNodes);
|
||||
findNodesInLoop(latchNode, intHead, this, intNodes);
|
||||
latchNode->flg |= IS_LATCH_NODE;
|
||||
}
|
||||
}
|
||||
@ -352,8 +348,8 @@ static boolT successor (Int s, Int h, Function * pProc)
|
||||
header = pProc->dfsLast[h];
|
||||
for (i = 0; i < header->numOutEdges; i++)
|
||||
if (header->edges[i].BBptr->dfsLastNum == s)
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -377,44 +373,43 @@ static void tagNodesInCase (BB * pBB, nodeList &l, Int head, Int tail)
|
||||
}
|
||||
|
||||
|
||||
static void structCases(Function * pProc)
|
||||
/* Structures case statements. This procedure is invoked only when pProc
|
||||
* has a case node. */
|
||||
{ Int i, j;
|
||||
void Function::structCases()
|
||||
{
|
||||
Int i, j;
|
||||
BB * caseHeader; /* case header node */
|
||||
Int exitNode = NO_NODE; /* case exit node */
|
||||
nodeList caseNodes; /* temporary: list of nodes in case */
|
||||
|
||||
/* Linear scan of the nodes in reverse dfsLast order, searching for
|
||||
* case nodes */
|
||||
for (i = pProc->numBBs - 1; i >= 0; i--)
|
||||
if (pProc->dfsLast[i]->nodeType == MULTI_BRANCH)
|
||||
for (i = numBBs - 1; i >= 0; i--)
|
||||
if (dfsLast[i]->nodeType == MULTI_BRANCH)
|
||||
{
|
||||
caseHeader = pProc->dfsLast[i];
|
||||
caseHeader = dfsLast[i];
|
||||
|
||||
/* Find descendant node which has as immediate predecessor
|
||||
* the current header node, and is not a successor. */
|
||||
for (j = i + 2; j < pProc->numBBs; j++)
|
||||
for (j = i + 2; j < numBBs; j++)
|
||||
{
|
||||
if ((!successor(j, i, pProc)) &&
|
||||
(pProc->dfsLast[j]->immedDom == i))
|
||||
if ((!successor(j, i, this)) &&
|
||||
(dfsLast[j]->immedDom == i))
|
||||
if (exitNode == NO_NODE)
|
||||
exitNode = j;
|
||||
else if (pProc->dfsLast[exitNode]->numInEdges <
|
||||
pProc->dfsLast[j]->numInEdges)
|
||||
else if (dfsLast[exitNode]->inEdges.size() < dfsLast[j]->inEdges.size())
|
||||
exitNode = j;
|
||||
}
|
||||
pProc->dfsLast[i]->caseTail = exitNode;
|
||||
dfsLast[i]->caseTail = exitNode;
|
||||
|
||||
/* Tag nodes that belong to the case by recording the
|
||||
* header field with caseHeader. */
|
||||
insertList (caseNodes, i);
|
||||
pProc->dfsLast[i]->caseHead = i;
|
||||
dfsLast[i]->caseHead = i;
|
||||
for (j = 0; j < caseHeader->numOutEdges; j++)
|
||||
tagNodesInCase (caseHeader->edges[j].BBptr, caseNodes, i,
|
||||
exitNode);
|
||||
tagNodesInCase (caseHeader->edges[j].BBptr, caseNodes, i, exitNode);
|
||||
if (exitNode != NO_NODE)
|
||||
pProc->dfsLast[exitNode]->caseHead = i;
|
||||
dfsLast[exitNode]->caseHead = i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,42 +429,42 @@ static void flagNodes (nodeList &l, Int f, Function * pProc)
|
||||
}
|
||||
|
||||
|
||||
static void structIfs (Function * pProc)
|
||||
/* Structures if statements */
|
||||
{ Int curr, /* Index for linear scan of nodes */
|
||||
void Function::structIfs ()
|
||||
{
|
||||
Int curr, /* Index for linear scan of nodes */
|
||||
desc, /* Index for descendant */
|
||||
followInEdges, /* Largest # in-edges so far */
|
||||
follow; /* Possible follow node */
|
||||
nodeList domDesc, /* List of nodes dominated by curr */
|
||||
unresolved, /* List of unresolved if nodes */
|
||||
*l; /* Temporary list */
|
||||
unresolved /* List of unresolved if nodes */
|
||||
;
|
||||
BB * currNode, /* Pointer to current node */
|
||||
* pbb;
|
||||
|
||||
/* Linear scan of nodes in reverse dfsLast order */
|
||||
for (curr = pProc->numBBs - 1; curr >= 0; curr--)
|
||||
for (curr = numBBs - 1; curr >= 0; curr--)
|
||||
{
|
||||
currNode = pProc->dfsLast[curr];
|
||||
currNode = dfsLast[curr];
|
||||
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
|
||||
continue;
|
||||
|
||||
if ((currNode->nodeType == TWO_BRANCH) &&
|
||||
(! (pProc->Icode.GetLlFlag(currNode->start + currNode->length - 1)
|
||||
& JX_LOOP)))
|
||||
if ((currNode->nodeType == TWO_BRANCH) && (!currNode->back().isLlFlag(JX_LOOP)))
|
||||
{
|
||||
followInEdges = 0;
|
||||
follow = 0;
|
||||
|
||||
/* Find all nodes that have this node as immediate dominator */
|
||||
for (desc = curr+1; desc < pProc->numBBs; desc++)
|
||||
for (desc = curr+1; desc < numBBs; desc++)
|
||||
{
|
||||
if (pProc->dfsLast[desc]->immedDom == curr) {
|
||||
if (dfsLast[desc]->immedDom == curr)
|
||||
{
|
||||
insertList (domDesc, desc);
|
||||
pbb = pProc->dfsLast[desc];
|
||||
if ((pbb->numInEdges - pbb->numBackEdges) >= followInEdges)
|
||||
pbb = dfsLast[desc];
|
||||
if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges)
|
||||
{
|
||||
follow = desc;
|
||||
followInEdges = pbb->numInEdges - pbb->numBackEdges;
|
||||
followInEdges = pbb->inEdges.size() - pbb->numBackEdges;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -480,7 +475,7 @@ static void structIfs (Function * pProc)
|
||||
{
|
||||
currNode->ifFollow = follow;
|
||||
if (!unresolved.empty())
|
||||
flagNodes (unresolved, follow, pProc);
|
||||
flagNodes (unresolved, follow, this);
|
||||
}
|
||||
else
|
||||
insertList (unresolved, curr);
|
||||
@ -515,178 +510,170 @@ void Function::compoundCond()
|
||||
if (pbb->flg & INVALID_BB)
|
||||
continue;
|
||||
|
||||
if (pbb->nodeType == TWO_BRANCH)
|
||||
if (pbb->nodeType != TWO_BRANCH)
|
||||
continue;
|
||||
|
||||
t = pbb->edges[THEN].BBptr;
|
||||
e = pbb->edges[ELSE].BBptr;
|
||||
|
||||
/* Check (X || Y) case */
|
||||
if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) &&
|
||||
(t->inEdges.size() == 1) && (t->edges[ELSE].BBptr == e))
|
||||
{
|
||||
t = pbb->edges[THEN].BBptr;
|
||||
e = pbb->edges[ELSE].BBptr;
|
||||
obb = t->edges[THEN].BBptr;
|
||||
|
||||
/* Check (X || Y) case */
|
||||
if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) &&
|
||||
(t->numInEdges == 1) && (t->edges[ELSE].BBptr == e))
|
||||
/* Construct compound DBL_OR expression */
|
||||
picode = &pbb->back();
|
||||
ticode = &t->back();
|
||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||
ticode->ic.hl.oper.exp, DBL_OR);
|
||||
picode->ic.hl.oper.exp = exp;
|
||||
|
||||
/* Replace in-edge to obb from t to pbb */
|
||||
{
|
||||
obb = t->edges[THEN].BBptr;
|
||||
|
||||
/* Construct compound DBL_OR expression */
|
||||
picode = this->Icode.GetIcode(pbb->start + pbb->length -1);
|
||||
ticode = this->Icode.GetIcode(t->start + t->length -1);
|
||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||
ticode->ic.hl.oper.exp, DBL_OR);
|
||||
picode->ic.hl.oper.exp = exp;
|
||||
|
||||
/* Replace in-edge to obb from t to pbb */
|
||||
for (j = 0; j < obb->numInEdges; j++)
|
||||
if (obb->inEdges[j] == t)
|
||||
{
|
||||
obb->inEdges[j] = pbb;
|
||||
break;
|
||||
}
|
||||
|
||||
/* New THEN out-edge of pbb */
|
||||
pbb->edges[THEN].BBptr = obb;
|
||||
|
||||
/* Remove in-edge t to e */
|
||||
auto iter=std::find(e->inEdges.begin(),e->inEdges.end(),t);
|
||||
assert(iter!=e->inEdges.end());
|
||||
e->inEdges.erase(iter);
|
||||
e->numInEdges--; /* looses 1 arc */
|
||||
assert(e->numInEdges==e->inEdges.size());
|
||||
t->flg |= INVALID_BB;
|
||||
|
||||
if (pbb->flg & IS_LATCH_NODE)
|
||||
this->dfsLast[t->dfsLastNum] = pbb;
|
||||
else
|
||||
i--; /* to repeat this analysis */
|
||||
|
||||
change = TRUE;
|
||||
auto iter=find(obb->inEdges.begin(),obb->inEdges.end(),t);
|
||||
if(iter!=obb->inEdges.end())
|
||||
*iter = pbb;
|
||||
}
|
||||
|
||||
/* Check (!X && Y) case */
|
||||
else if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) &&
|
||||
(t->numInEdges == 1) && (t->edges[THEN].BBptr == e))
|
||||
{
|
||||
obb = t->edges[ELSE].BBptr;
|
||||
/* New THEN out-edge of pbb */
|
||||
pbb->edges[THEN].BBptr = obb;
|
||||
|
||||
/* Construct compound DBL_AND expression */
|
||||
picode = this->Icode.GetIcode(pbb->start + pbb->length -1);
|
||||
ticode = this->Icode.GetIcode(t->start + t->length -1);
|
||||
inverseCondOp (&picode->ic.hl.oper.exp);
|
||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||
ticode->ic.hl.oper.exp, DBL_AND);
|
||||
picode->ic.hl.oper.exp = exp;
|
||||
/* Remove in-edge t to e */
|
||||
auto iter=std::find(e->inEdges.begin(),e->inEdges.end(),t);
|
||||
assert(iter!=e->inEdges.end());
|
||||
e->inEdges.erase(iter);
|
||||
t->flg |= INVALID_BB;
|
||||
|
||||
/* Replace in-edge to obb from t to pbb */
|
||||
auto iter=std::find(obb->inEdges.begin(),obb->inEdges.end(),t);
|
||||
assert(iter!=obb->inEdges.end());
|
||||
*iter=pbb;
|
||||
if (pbb->flg & IS_LATCH_NODE)
|
||||
this->dfsLast[t->dfsLastNum] = pbb;
|
||||
else
|
||||
i--; /* to repeat this analysis */
|
||||
|
||||
/* New THEN and ELSE out-edges of pbb */
|
||||
pbb->edges[THEN].BBptr = e;
|
||||
pbb->edges[ELSE].BBptr = obb;
|
||||
change = TRUE;
|
||||
}
|
||||
|
||||
/* Remove in-edge t to e */
|
||||
iter=std::find(e->inEdges.begin(),e->inEdges.end(),t);
|
||||
assert(iter!=e->inEdges.end());
|
||||
e->inEdges.erase(iter); /* looses 1 arc */
|
||||
e->numInEdges--; /* looses 1 arc */
|
||||
assert(t->inEdges.size()==t->numInEdges);
|
||||
t->flg |= INVALID_BB;
|
||||
/* Check (!X && Y) case */
|
||||
else if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) &&
|
||||
(t->inEdges.size() == 1) && (t->edges[THEN].BBptr == e))
|
||||
{
|
||||
obb = t->edges[ELSE].BBptr;
|
||||
|
||||
if (pbb->flg & IS_LATCH_NODE)
|
||||
this->dfsLast[t->dfsLastNum] = pbb;
|
||||
else
|
||||
i--; /* to repeat this analysis */
|
||||
/* Construct compound DBL_AND expression */
|
||||
picode = &pbb->back();
|
||||
ticode = &t->back();
|
||||
|
||||
change = TRUE;
|
||||
}
|
||||
inverseCondOp (&picode->ic.hl.oper.exp);
|
||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||
ticode->ic.hl.oper.exp, DBL_AND);
|
||||
picode->ic.hl.oper.exp = exp;
|
||||
|
||||
/* Check (X && Y) case */
|
||||
else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) &&
|
||||
(e->numInEdges == 1) && (e->edges[THEN].BBptr == t))
|
||||
{
|
||||
obb = e->edges[ELSE].BBptr;
|
||||
/* Replace in-edge to obb from t to pbb */
|
||||
auto iter=std::find(obb->inEdges.begin(),obb->inEdges.end(),t);
|
||||
assert(iter!=obb->inEdges.end());
|
||||
*iter=pbb;
|
||||
|
||||
/* Construct compound DBL_AND expression */
|
||||
picode = this->Icode.GetIcode(pbb->start + pbb->length -1);
|
||||
ticode = this->Icode.GetIcode(t->start + t->length -1);
|
||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||
ticode->ic.hl.oper.exp, DBL_AND);
|
||||
picode->ic.hl.oper.exp = exp;
|
||||
/* New THEN and ELSE out-edges of pbb */
|
||||
pbb->edges[THEN].BBptr = e;
|
||||
pbb->edges[ELSE].BBptr = obb;
|
||||
|
||||
/* Replace in-edge to obb from e to pbb */
|
||||
auto iter = std::find(obb->inEdges.begin(),obb->inEdges.end(),e);
|
||||
assert(iter!=obb->inEdges.end());
|
||||
*iter=pbb;
|
||||
/* New ELSE out-edge of pbb */
|
||||
pbb->edges[ELSE].BBptr = obb;
|
||||
/* Remove in-edge t to e */
|
||||
iter=std::find(e->inEdges.begin(),e->inEdges.end(),t);
|
||||
assert(iter!=e->inEdges.end());
|
||||
e->inEdges.erase(iter); /* looses 1 arc */
|
||||
t->flg |= INVALID_BB;
|
||||
|
||||
/* Remove in-edge e to t */
|
||||
iter = std::find(t->inEdges.begin(),t->inEdges.end(),e);
|
||||
assert(iter!=t->inEdges.end());
|
||||
t->inEdges.erase(iter);
|
||||
t->numInEdges--; /* looses 1 arc */
|
||||
assert(t->inEdges.size()==t->numInEdges);
|
||||
e->flg |= INVALID_BB;
|
||||
if (pbb->flg & IS_LATCH_NODE)
|
||||
this->dfsLast[t->dfsLastNum] = pbb;
|
||||
else
|
||||
i--; /* to repeat this analysis */
|
||||
|
||||
if (pbb->flg & IS_LATCH_NODE)
|
||||
this->dfsLast[e->dfsLastNum] = pbb;
|
||||
else
|
||||
i--; /* to repeat this analysis */
|
||||
change = TRUE;
|
||||
}
|
||||
|
||||
change = TRUE;
|
||||
}
|
||||
/* Check (X && Y) case */
|
||||
else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) &&
|
||||
(e->inEdges.size()==1) && (e->edges[THEN].BBptr == t))
|
||||
{
|
||||
obb = e->edges[ELSE].BBptr;
|
||||
|
||||
/* Check (!X || Y) case */
|
||||
else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) &&
|
||||
(e->numInEdges == 1) && (e->edges[ELSE].BBptr == t))
|
||||
{
|
||||
obb = e->edges[THEN].BBptr;
|
||||
/* Construct compound DBL_AND expression */
|
||||
picode = &pbb->back();
|
||||
ticode = &t->back();
|
||||
|
||||
/* Construct compound DBL_OR expression */
|
||||
picode = this->Icode.GetIcode(pbb->start + pbb->length -1);
|
||||
ticode = this->Icode.GetIcode(t->start + t->length -1);
|
||||
inverseCondOp (&picode->ic.hl.oper.exp);
|
||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||
ticode->ic.hl.oper.exp, DBL_OR);
|
||||
picode->ic.hl.oper.exp = exp;
|
||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||
ticode->ic.hl.oper.exp, DBL_AND);
|
||||
picode->ic.hl.oper.exp = exp;
|
||||
|
||||
/* Replace in-edge to obb from e to pbb */
|
||||
assert(obb->numInEdges==obb->inEdges.size());
|
||||
auto iter = std::find(obb->inEdges.begin(),obb->inEdges.end(),e);
|
||||
assert(iter!=obb->inEdges.end());
|
||||
*iter=pbb;
|
||||
/* Replace in-edge to obb from e to pbb */
|
||||
auto iter = std::find(obb->inEdges.begin(),obb->inEdges.end(),e);
|
||||
assert(iter!=obb->inEdges.end());
|
||||
*iter=pbb;
|
||||
/* New ELSE out-edge of pbb */
|
||||
pbb->edges[ELSE].BBptr = obb;
|
||||
|
||||
/* New THEN and ELSE out-edges of pbb */
|
||||
pbb->edges[THEN].BBptr = obb;
|
||||
pbb->edges[ELSE].BBptr = t;
|
||||
/* Remove in-edge e to t */
|
||||
iter = std::find(t->inEdges.begin(),t->inEdges.end(),e);
|
||||
assert(iter!=t->inEdges.end());
|
||||
t->inEdges.erase(iter);
|
||||
e->flg |= INVALID_BB;
|
||||
|
||||
/* Remove in-edge e to t */
|
||||
iter = std::find(t->inEdges.begin(),t->inEdges.end(),e);
|
||||
assert(iter!=t->inEdges.end());
|
||||
t->inEdges.erase(iter);
|
||||
t->numInEdges--; /* looses 1 arc */
|
||||
assert(t->numInEdges=t->inEdges.size());
|
||||
e->flg |= INVALID_BB;
|
||||
if (pbb->flg & IS_LATCH_NODE)
|
||||
this->dfsLast[e->dfsLastNum] = pbb;
|
||||
else
|
||||
i--; /* to repeat this analysis */
|
||||
|
||||
if (pbb->flg & IS_LATCH_NODE)
|
||||
this->dfsLast[e->dfsLastNum] = pbb;
|
||||
else
|
||||
i--; /* to repeat this analysis */
|
||||
change = TRUE;
|
||||
}
|
||||
|
||||
change = TRUE;
|
||||
}
|
||||
/* Check (!X || Y) case */
|
||||
else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) &&
|
||||
(e->inEdges.size() == 1) && (e->edges[ELSE].BBptr == t))
|
||||
{
|
||||
obb = e->edges[THEN].BBptr;
|
||||
|
||||
/* Construct compound DBL_OR expression */
|
||||
picode = &pbb->back();
|
||||
ticode = &t->back();
|
||||
inverseCondOp (&picode->ic.hl.oper.exp);
|
||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||
ticode->ic.hl.oper.exp, DBL_OR);
|
||||
picode->ic.hl.oper.exp = exp;
|
||||
|
||||
/* Replace in-edge to obb from e to pbb */
|
||||
auto iter = std::find(obb->inEdges.begin(),obb->inEdges.end(),e);
|
||||
assert(iter!=obb->inEdges.end());
|
||||
*iter=pbb;
|
||||
|
||||
/* New THEN and ELSE out-edges of pbb */
|
||||
pbb->edges[THEN].BBptr = obb;
|
||||
pbb->edges[ELSE].BBptr = t;
|
||||
|
||||
/* Remove in-edge e to t */
|
||||
iter = std::find(t->inEdges.begin(),t->inEdges.end(),e);
|
||||
assert(iter!=t->inEdges.end());
|
||||
t->inEdges.erase(iter);
|
||||
e->flg |= INVALID_BB;
|
||||
|
||||
if (pbb->flg & IS_LATCH_NODE)
|
||||
this->dfsLast[e->dfsLastNum] = pbb;
|
||||
else
|
||||
i--; /* to repeat this analysis */
|
||||
|
||||
change = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Function::structure(derSeq *derivedG)
|
||||
/* Structuring algorithm to find the structures of the graph pProc->cfg */
|
||||
void Function::structure(derSeq *derivedG)
|
||||
{
|
||||
/* Find immediate dominators of the graph */
|
||||
findImmedDom();
|
||||
if (hasCase)
|
||||
structCases(this);
|
||||
structLoops(this, derivedG);
|
||||
structIfs(this);
|
||||
structCases();
|
||||
structLoops(derivedG);
|
||||
structIfs();
|
||||
}
|
||||
|
||||
@ -24,7 +24,8 @@ Int STKFRAME::getLocVar(Int off)
|
||||
|
||||
/* Returns a string with the source operand of Icode */
|
||||
static COND_EXPR *srcIdent (ICODE * Icode, Function * pProc, Int i, ICODE * duIcode, operDu du)
|
||||
{ COND_EXPR *n;
|
||||
{
|
||||
COND_EXPR *n;
|
||||
|
||||
if (Icode->ic.ll.flg & I) /* immediate operand */
|
||||
{
|
||||
@ -99,7 +100,7 @@ void Function::elimCondCodes ()
|
||||
|
||||
case iOR:
|
||||
lhs = Icode.GetIcode(defAt-1)->ic.hl.oper.asgn.lhs->clone();
|
||||
copyDU (Icode.GetIcode(useAt-1),Icode.GetIcode(defAt-1), eUSE, eDEF);
|
||||
Icode[useAt-1].copyDU(Icode[defAt-1], eUSE, eDEF);
|
||||
if (Icode.GetLlFlag(defAt-1) & B)
|
||||
rhs = COND_EXPR::idKte (0, 1);
|
||||
else
|
||||
@ -164,8 +165,8 @@ void Function::elimCondCodes ()
|
||||
{
|
||||
exp = prev->ic.hl.oper.exp->clone();
|
||||
exp->changeBoolOp (condOpJCond[Icode.GetLlOpcode(useAt-1)-iJB]);
|
||||
copyDU (Icode.GetIcode(useAt-1), prev, eUSE, eUSE);
|
||||
Icode.GetIcode(useAt-1)->setJCond(exp);
|
||||
Icode[useAt-1].copyDU(*prev, eUSE, eUSE);
|
||||
Icode[useAt-1].setJCond(exp);
|
||||
}
|
||||
}
|
||||
/* Error - definition not found for use of a cond code */
|
||||
@ -452,8 +453,7 @@ void Function::genDU1 ()
|
||||
{
|
||||
if (! (pbb->liveOut & duReg[regi])) /* not liveOut */
|
||||
{
|
||||
res = removeDefRegi (regi, picode, defRegIdx+1,
|
||||
&localId);
|
||||
res = picode->removeDefRegi (regi, defRegIdx+1,&localId);
|
||||
|
||||
/* Backpatch any uses of this instruction, within
|
||||
* the same BB, if the instruction was invalidated */
|
||||
@ -567,7 +567,7 @@ static boolT xClear (COND_EXPR *rhs, Int f, Int t, Int lastBBinst, Function * pp
|
||||
ICODE * picode;
|
||||
|
||||
if (rhs == NULL)
|
||||
return (FALSE);
|
||||
return false;
|
||||
|
||||
switch (rhs->type) {
|
||||
case IDENTIFIER:
|
||||
@ -580,15 +580,15 @@ static boolT xClear (COND_EXPR *rhs, Int f, Int t, Int lastBBinst, Function * pp
|
||||
(picode[i].invalid == FALSE))
|
||||
{
|
||||
if (picode[i].du.def & duReg[regi])
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
if (i < lastBBinst)
|
||||
return (TRUE);
|
||||
return true;
|
||||
else
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return (TRUE);
|
||||
return true;
|
||||
/* else if (rhs->expr.ident.idType == LONG_VAR)
|
||||
{
|
||||
missing all other identifiers ****
|
||||
@ -597,7 +597,7 @@ missing all other identifiers ****
|
||||
case BOOLEAN_OP:
|
||||
res = xClear (rhs->expr.boolExpr.rhs, f, t, lastBBinst, pproc);
|
||||
if (res == FALSE)
|
||||
return (FALSE);
|
||||
return false;
|
||||
return (xClear (rhs->expr.boolExpr.lhs, f, t, lastBBinst, pproc));
|
||||
|
||||
case NEGATION:
|
||||
@ -652,7 +652,7 @@ static void processCArg (Function * pp, Function * pProc, ICODE * picode, Int nu
|
||||
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
|
||||
void Function::findExps()
|
||||
{
|
||||
Int i, j, k, lastInst, lastInstN, numHlIcodes;
|
||||
Int i, j, k, lastInst, numHlIcodes;
|
||||
ICODE * picode, /* Current icode */
|
||||
* ticode; /* Target icode */
|
||||
BB * pbb; /* Current and next basic block */
|
||||
@ -728,7 +728,7 @@ void Function::findExps()
|
||||
break;
|
||||
|
||||
case HLI_CALL: /* register arguments */
|
||||
newRegArg (this, picode, ticode);
|
||||
newRegArg (picode, ticode);
|
||||
picode->invalidate();
|
||||
numHlIcodes--;
|
||||
break;
|
||||
@ -866,7 +866,7 @@ void Function::findExps()
|
||||
break;
|
||||
|
||||
case HLI_CALL: /* register arguments */
|
||||
newRegArg (this, picode, ticode);
|
||||
newRegArg ( picode, ticode);
|
||||
picode->invalidate();
|
||||
numHlIcodes--;
|
||||
break;
|
||||
|
||||
@ -23,7 +23,7 @@ PROG prog; /* programs fields */
|
||||
OPTION option; /* Command line options */
|
||||
//Function * pProcList; /* List of procedures, topologically sort */
|
||||
//Function * pLastProc; /* Pointer to last node in procedure list */
|
||||
std::list<Function> pProcList;
|
||||
FunctionListType pProcList;
|
||||
CALL_GRAPH *callGraph; /* Call graph of the program */
|
||||
|
||||
static char *initargs(int argc, char *argv[]);
|
||||
|
||||
@ -1483,17 +1483,17 @@ boolT callArg(word off, char *sym)
|
||||
|
||||
imageOff = off + ((dword)pProc->state.r[rCS] << 4);
|
||||
/* Search procedure list for one with appropriate entry point */
|
||||
std::list<Function>::iterator iter= std::find_if(pProcList.begin(),pProcList.end(),
|
||||
FunctionListType::iterator iter= std::find_if(pProcList.begin(),pProcList.end(),
|
||||
[imageOff](const Function &f) -> bool { return f.procEntry==imageOff; });
|
||||
if(iter==pProcList.end())
|
||||
{
|
||||
/* No existing proc entry */
|
||||
//ERROR: dereferencing NULL !?!
|
||||
//LibCheck(*iter);
|
||||
Function x;
|
||||
x.procEntry=imageOff;
|
||||
LibCheck(x);
|
||||
if (x.flg & PROC_ISLIB)
|
||||
Function *x=Function::Create();
|
||||
x->procEntry=imageOff;
|
||||
LibCheck(*x);
|
||||
if (x->flg & PROC_ISLIB)
|
||||
{
|
||||
/* No entry for this proc, but it is a library function.
|
||||
Create an entry for it */
|
||||
|
||||
@ -22,20 +22,20 @@ static void dfsNumbering(BB * pBB, std::vector<BB*> &dfsLast, Int *first, Int *l
|
||||
void Function::createCFG()
|
||||
{
|
||||
/* Splits Icode associated with the procedure into Basic Blocks.
|
||||
* The links between BBs represent the control flow graph of the
|
||||
* procedure.
|
||||
* A Basic Block is defined to end on one of the following instructions:
|
||||
* 1) Conditional and unconditional jumps
|
||||
* 2) CALL(F)
|
||||
* 3) RET(F)
|
||||
* 4) On the instruction before a join (a flagged TARGET)
|
||||
* 5) Repeated string instructions
|
||||
* 6) End of procedure
|
||||
*/
|
||||
* The links between BBs represent the control flow graph of the
|
||||
* procedure.
|
||||
* A Basic Block is defined to end on one of the following instructions:
|
||||
* 1) Conditional and unconditional jumps
|
||||
* 2) CALL(F)
|
||||
* 3) RET(F)
|
||||
* 4) On the instruction before a join (a flagged TARGET)
|
||||
* 5) Repeated string instructions
|
||||
* 6) End of procedure
|
||||
*/
|
||||
Int i;
|
||||
Int ip, start;
|
||||
BB * psBB;
|
||||
BB * pBB;
|
||||
BB * psBB;
|
||||
BB * pBB;
|
||||
ICODE * pIcode = Icode.GetFirstIcode();
|
||||
|
||||
stats.numBBbef = stats.numBBaft = 0;
|
||||
@ -47,7 +47,9 @@ void Function::createCFG()
|
||||
! (pIcode->ic.ll.flg & TERMINATES) &&
|
||||
pIcode->ic.ll.opcode != iJMP && pIcode->ic.ll.opcode != iJMPF &&
|
||||
pIcode->ic.ll.opcode != iRET && pIcode->ic.ll.opcode != iRETF)
|
||||
{
|
||||
pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this);
|
||||
}
|
||||
|
||||
/* Only process icodes that have valid instructions */
|
||||
else if ((pIcode->ic.ll.flg & NO_CODE) != NO_CODE)
|
||||
@ -64,7 +66,10 @@ CondJumps:
|
||||
pBB->edges[0].ip = (dword)start;
|
||||
/* This is for jumps off into nowhere */
|
||||
if (pIcode->ic.ll.flg & NO_LABEL)
|
||||
{
|
||||
pBB->numOutEdges--;
|
||||
pBB->edges.pop_back();
|
||||
}
|
||||
else
|
||||
pBB->edges[1].ip = pIcode->ic.ll.immed.op;
|
||||
break;
|
||||
@ -76,13 +81,13 @@ CondJumps:
|
||||
case iJMPF: case iJMP:
|
||||
if (pIcode->ic.ll.flg & SWITCH)
|
||||
{
|
||||
pBB = BB::Create(start, ip, MULTI_BRANCH,
|
||||
pIcode->ic.ll.caseTbl.numEntries, this);
|
||||
pBB = BB::Create(start, ip, MULTI_BRANCH, pIcode->ic.ll.caseTbl.numEntries, this);
|
||||
for (i = 0; i < pIcode->ic.ll.caseTbl.numEntries; i++)
|
||||
pBB->edges[i].ip = pIcode->ic.ll.caseTbl.entries[i];
|
||||
hasCase = TRUE;
|
||||
}
|
||||
else if ((pIcode->ic.ll.flg & (I | NO_LABEL)) == I) {
|
||||
else if ((pIcode->ic.ll.flg & (I | NO_LABEL)) == I)
|
||||
{
|
||||
pBB = BB::Create(start, ip, ONE_BRANCH, 1, this);
|
||||
pBB->edges[0].ip = pIcode->ic.ll.immed.op;
|
||||
}
|
||||
@ -137,17 +142,17 @@ CondJumps:
|
||||
{
|
||||
ip = pBB->edges[i].ip;
|
||||
if (ip >= SYNTHESIZED_MIN)
|
||||
fatalError (INVALID_SYNTHETIC_BB);
|
||||
else
|
||||
{
|
||||
auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(),
|
||||
[ip](BB *psBB)->bool {return psBB->start==ip;});
|
||||
fatalError (INVALID_SYNTHETIC_BB);
|
||||
return ;
|
||||
}
|
||||
auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(),
|
||||
[ip](BB *psBB)->bool {return psBB->begin()==ip;});
|
||||
if(iter2==heldBBs.end())
|
||||
fatalError(NO_BB, ip, name);
|
||||
psBB = *iter2;
|
||||
pBB->edges[i].BBptr = psBB;
|
||||
psBB->numInEdges++;
|
||||
}
|
||||
psBB->inEdges.push_back(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -203,19 +208,19 @@ void Function::compressCFG()
|
||||
for (;iter!=cfg.end(); ++iter)
|
||||
{
|
||||
pBB = *iter;
|
||||
pBB->inEdges.resize(pBB->numInEdges,0);
|
||||
if (pBB->numInEdges != 0 && (pBB->nodeType == ONE_BRANCH || pBB->nodeType == TWO_BRANCH))
|
||||
for (i = 0; i < pBB->numOutEdges; i++)
|
||||
{
|
||||
ip = pBB->start + pBB->length - 1;
|
||||
pNxt = rmJMP(this, ip, pBB->edges[i].BBptr);
|
||||
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
|
||||
continue;
|
||||
for (i = 0; i < pBB->numOutEdges; i++)
|
||||
{
|
||||
ip = pBB->rbegin();
|
||||
pNxt = rmJMP(this, ip, pBB->edges[i].BBptr);
|
||||
|
||||
if (pBB->numOutEdges) /* Might have been clobbered */
|
||||
{
|
||||
pBB->edges[i].BBptr = pNxt;
|
||||
Icode.SetImmediateOp(ip, (dword)pNxt->start);
|
||||
}
|
||||
if (pBB->numOutEdges) /* Might have been clobbered */
|
||||
{
|
||||
pBB->edges[i].BBptr = pNxt;
|
||||
Icode.SetImmediateOp(ip, (dword)pNxt->start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Next is a depth-first traversal merging any FALL_NODE or
|
||||
@ -230,7 +235,7 @@ void Function::compressCFG()
|
||||
for(auto iter=cfg.begin(); iter!=cfg.end(); ++iter)
|
||||
{
|
||||
pBB = *iter;
|
||||
if (pBB->numInEdges == 0)
|
||||
if (pBB->inEdges.empty())
|
||||
{
|
||||
if (iter == cfg.begin()) /* Init it misses out on */
|
||||
pBB->index = UN_INIT;
|
||||
@ -244,7 +249,7 @@ void Function::compressCFG()
|
||||
}
|
||||
else
|
||||
{
|
||||
pBB->inEdgeCount = pBB->numInEdges;
|
||||
pBB->inEdgeCount = pBB->inEdges.size();
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,11 +270,16 @@ static BB * rmJMP(Function * pProc, Int marker, BB * pBB)
|
||||
{
|
||||
marker += DFS_JMP;
|
||||
|
||||
while (pBB->nodeType == ONE_BRANCH && pBB->length == 1) {
|
||||
if (pBB->traversed != marker) {
|
||||
while (pBB->nodeType == ONE_BRANCH && pBB->length == 1)
|
||||
{
|
||||
if (pBB->traversed != marker)
|
||||
{
|
||||
pBB->traversed = marker;
|
||||
if (--pBB->numInEdges)
|
||||
pBB->edges[0].BBptr->numInEdges++;
|
||||
pBB->inEdges.pop_back();
|
||||
if (not pBB->inEdges.empty())
|
||||
{
|
||||
pBB->edges[0].BBptr->inEdges.push_back(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pProc->Icode.SetLlFlag(pBB->start, NO_CODE);
|
||||
@ -284,7 +294,8 @@ static BB * rmJMP(Function * pProc, Int marker, BB * pBB)
|
||||
pProc->Icode.SetImmediateOp(pBB->start, (dword)pBB->start);
|
||||
do {
|
||||
pBB = pBB->edges[0].BBptr;
|
||||
if (! --pBB->numInEdges)
|
||||
pBB->inEdges.pop_back(); // was --numInedges
|
||||
if (! pBB->inEdges.empty())
|
||||
{
|
||||
pProc->Icode.SetLlFlag(pBB->start, NO_CODE);
|
||||
pProc->Icode.SetLlInvalid(pBB->start, TRUE);
|
||||
@ -328,7 +339,7 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
|
||||
|
||||
}
|
||||
/* If there's no other edges into child can merge */
|
||||
if (pChild->numInEdges != 1)
|
||||
if (pChild->inEdges.size() != 1)
|
||||
break;
|
||||
|
||||
nodeType = pChild->nodeType;
|
||||
@ -337,7 +348,8 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
|
||||
numOutEdges = pChild->numOutEdges;
|
||||
edges.swap(pChild->edges);
|
||||
|
||||
pChild->numOutEdges = pChild->numInEdges = 0;
|
||||
pChild->numOutEdges = 0;
|
||||
pChild->inEdges.clear();
|
||||
pChild->edges.clear();
|
||||
}
|
||||
traversed = DFS_MERGE;
|
||||
@ -368,7 +380,7 @@ void BB::dfsNumbering(std::vector<BB *> &dfsLast, Int *first, Int *last)
|
||||
pChild->inEdges[pChild->index++] = this;
|
||||
|
||||
/* Is this the last visit? */
|
||||
if (pChild->index == pChild->numInEdges)
|
||||
if (pChild->index == pChild->inEdges.size())
|
||||
pChild->index = UN_INIT;
|
||||
|
||||
if (pChild->traversed != DFS_NUM)
|
||||
|
||||
@ -83,37 +83,39 @@ void ICODE ::invalidate()
|
||||
/* Removes the defined register regi from the lhs subtree. If all registers
|
||||
* of this instruction are unused, the instruction is invalidated (ie.
|
||||
* removed) */
|
||||
boolT removeDefRegi (byte regi, ICODE *picode, Int thisDefIdx, LOCAL_ID *locId)
|
||||
{ Int numDefs;
|
||||
boolT ICODE::removeDefRegi (byte regi, Int thisDefIdx, LOCAL_ID *locId)
|
||||
{
|
||||
Int numDefs;
|
||||
|
||||
numDefs = picode->du1.numRegsDef;
|
||||
numDefs = du1.numRegsDef;
|
||||
if (numDefs == thisDefIdx)
|
||||
for ( ; numDefs > 0; numDefs--)
|
||||
{
|
||||
if ((picode->du1.idx[numDefs-1][0] != 0)||(picode->du.lastDefRegi))
|
||||
if ((du1.idx[numDefs-1][0] != 0)||(du.lastDefRegi))
|
||||
break;
|
||||
}
|
||||
|
||||
if (numDefs == 0)
|
||||
{
|
||||
picode->invalidate();
|
||||
return (TRUE);
|
||||
invalidate();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (picode->ic.hl.opcode) {
|
||||
case HLI_ASSIGN: removeRegFromLong (regi, locId,
|
||||
picode->ic.hl.oper.asgn.lhs);
|
||||
picode->du1.numRegsDef--;
|
||||
picode->du.def &= maskDuReg[regi];
|
||||
switch (ic.hl.opcode) {
|
||||
case HLI_ASSIGN:
|
||||
removeRegFromLong (regi, locId,ic.hl.oper.asgn.lhs);
|
||||
du1.numRegsDef--;
|
||||
du.def &= maskDuReg[regi];
|
||||
break;
|
||||
case HLI_POP:
|
||||
case HLI_PUSH: removeRegFromLong (regi, locId, picode->ic.hl.oper.exp);
|
||||
picode->du1.numRegsDef--;
|
||||
picode->du.def &= maskDuReg[regi];
|
||||
case HLI_PUSH:
|
||||
removeRegFromLong (regi, locId, ic.hl.oper.exp);
|
||||
du1.numRegsDef--;
|
||||
du.def &= maskDuReg[regi];
|
||||
break;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "dcc.h"
|
||||
#include "types.h" // Common types like byte, etc
|
||||
#include "ast.h" // Some icode types depend on these
|
||||
#include "icode.h"
|
||||
@ -118,6 +119,27 @@ ICODE * CIcodeRec::GetIcode(int ip)
|
||||
return &at(ip);
|
||||
}
|
||||
|
||||
extern char *indent(int level);
|
||||
extern Int getNextLabel();
|
||||
extern bundle cCode;
|
||||
/* Checks the given icode to determine whether it has a label associated
|
||||
* to it. If so, a goto is emitted to this label; otherwise, a new label
|
||||
* is created and a goto is also emitted.
|
||||
* Note: this procedure is to be used when the label is to be backpatched
|
||||
* onto code in cCode.code */
|
||||
void ICODE::emitGotoLabel (Int indLevel)
|
||||
{
|
||||
if (! (ic.ll.flg & HLL_LABEL)) /* node hasn't got a lab */
|
||||
{
|
||||
/* Generate new label */
|
||||
ic.ll.hllLabNum = getNextLabel();
|
||||
ic.ll.flg |= HLL_LABEL;
|
||||
|
||||
|
||||
/* Node has been traversed already, so backpatch this label into
|
||||
* the code */
|
||||
addLabelBundle (cCode.code, codeIdx, ic.ll.hllLabNum);
|
||||
}
|
||||
cCode.appendCode( "%sgoto L%ld;\n", indent(indLevel), ic.ll.hllLabNum);
|
||||
stats.numHLIcode++;
|
||||
}
|
||||
|
||||
|
||||
@ -324,8 +324,8 @@ static boolT idiom5 (ICODE * pIcode, ICODE * pEnd)
|
||||
{
|
||||
if (pIcode < pEnd)
|
||||
if ((pIcode+1)->ic.ll.opcode == iADC)
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -343,8 +343,8 @@ static boolT idiom6 (ICODE * pIcode, ICODE * pEnd)
|
||||
{
|
||||
if (pIcode < pEnd)
|
||||
if ((pIcode+1)->ic.ll.opcode == iSBB)
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -364,21 +364,21 @@ static boolT idiom7 (ICODE * pIcode)
|
||||
if (dst->regi == 0) /* global variable */
|
||||
{
|
||||
if ((dst->segValue == src->segValue) && (dst->off == src->off))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
else if (dst->regi < INDEXBASE) /* register */
|
||||
{
|
||||
if (dst->regi == src->regi)
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
else if ((dst->off) && (dst->seg == rSS) && (dst->regi == INDEXBASE + 6))
|
||||
/* offset from BP */
|
||||
{
|
||||
if ((dst->off == src->off) && (dst->seg == src->seg) &&
|
||||
(dst->regi == src->regi))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -406,12 +406,12 @@ static boolT idiom21 (ICODE * picode, ICODE * pend)
|
||||
(dst->regi < INDEXBASE))
|
||||
{
|
||||
if ((dst->regi == rDX) && ((picode+1)->ic.ll.dst.regi == rAX))
|
||||
return (TRUE);
|
||||
return true;
|
||||
if ((dst->regi == rCX) && ((picode+1)->ic.ll.dst.regi == rBX))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -432,9 +432,9 @@ static boolT idiom8 (ICODE * pIcode, ICODE * pEnd)
|
||||
if (((pIcode+1)->ic.ll.opcode == iRCR) &&
|
||||
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
||||
((pIcode+1)->ic.ll.immed.op == 1))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -496,9 +496,9 @@ static boolT idiom12 (ICODE * pIcode, ICODE * pEnd)
|
||||
if (((pIcode+1)->ic.ll.opcode == iRCL) &&
|
||||
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
||||
((pIcode+1)->ic.ll.immed.op == 1))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -519,9 +519,9 @@ static boolT idiom9 (ICODE * pIcode, ICODE * pEnd)
|
||||
if (((pIcode+1)->ic.ll.opcode == iRCR) &&
|
||||
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
||||
((pIcode+1)->ic.ll.immed.op == 1))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -552,13 +552,13 @@ static boolT idiom10old (ICODE * pIcode, ICODE * pEnd)
|
||||
if (((pIcode+1)->ic.ll.opcode == iJNE) &&
|
||||
((pIcode+2)->ic.ll.opcode != iCMP) &&
|
||||
((pIcode+3)->ic.ll.opcode != iJE))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
else /* at the end of the procedure */
|
||||
if (((pIcode+1) < pEnd) && ((pIcode+1)->ic.ll.opcode == iJNE))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -664,14 +664,14 @@ static boolT idiom14 (ICODE * picode, ICODE * pend, byte *regL, byte *regH)
|
||||
if (*regH == (picode+1)->ic.ll.src.regi)
|
||||
{
|
||||
if ((*regL == rAX) && (*regH == rDX))
|
||||
return (TRUE);
|
||||
return true;
|
||||
if ((*regL == rBX) && (*regH == rCX))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -702,21 +702,21 @@ static boolT idiom11 (ICODE * pIcode, ICODE * pEnd)
|
||||
pIcode->ic.ll.dst.segValue) &&
|
||||
((pIcode+2)->ic.ll.dst.off ==
|
||||
pIcode->ic.ll.dst.off))
|
||||
return (TRUE);
|
||||
return true;
|
||||
break;
|
||||
case REGISTER: if ((pIcode+2)->ic.ll.dst.regi ==
|
||||
pIcode->ic.ll.dst.regi)
|
||||
return (TRUE);
|
||||
return true;
|
||||
break;
|
||||
case PARAM:
|
||||
case LOCAL_VAR: if ((pIcode+2)->ic.ll.dst.off ==
|
||||
pIcode->ic.ll.dst.off)
|
||||
return (TRUE);
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -746,10 +746,10 @@ static boolT idiom16 (ICODE * picode, ICODE * pend)
|
||||
((picode+1)->ic.ll.src.regi)) &&
|
||||
((picode+1)->ic.ll.dst.regi == regi) &&
|
||||
((picode+2)->ic.ll.dst.regi == regi))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -800,7 +800,7 @@ static boolT idiom18 (ICODE * picode, ICODE * pend, Function * pproc)
|
||||
((picode+1)->ic.ll.dst.regi == regi) &&
|
||||
(((picode+2)->ic.ll.opcode >= iJB) &&
|
||||
((picode+2)->ic.ll.opcode < iJCXZ)))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -817,11 +817,11 @@ static boolT idiom18 (ICODE * picode, ICODE * pend, Function * pproc)
|
||||
((picode+1)->ic.ll.dst.regi == regi) &&
|
||||
(((picode+2)->ic.ll.opcode >= iJB) &&
|
||||
((picode+2)->ic.ll.opcode < iJCXZ)))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -846,17 +846,17 @@ static boolT idiom19 (ICODE * picode, ICODE * pend, Function * pproc)
|
||||
((picode->ic.ll.dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
|
||||
if ((picode < pend) && ((picode+1)->ic.ll.opcode >= iJB) &&
|
||||
((picode+1)->ic.ll.opcode < iJCXZ))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
else if (picode->ic.ll.dst.off) /* stack variable */
|
||||
{
|
||||
if ((picode < pend) && ((picode+1)->ic.ll.opcode >= iJB) &&
|
||||
((picode+1)->ic.ll.opcode < iJCXZ))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
else /* indexed */
|
||||
/* not supported yet */ ;
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -908,7 +908,7 @@ static boolT idiom20 (ICODE * picode, ICODE * pend, Function * pproc)
|
||||
((picode+2)->ic.ll.dst.regi == regi) &&
|
||||
(((picode+3)->ic.ll.opcode >= iJB) &&
|
||||
((picode+3)->ic.ll.opcode < iJCXZ)))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -925,11 +925,11 @@ static boolT idiom20 (ICODE * picode, ICODE * pend, Function * pproc)
|
||||
((picode+2)->ic.ll.dst.regi == regi) &&
|
||||
(((picode+3)->ic.ll.opcode >= iJB) &&
|
||||
((picode+3)->ic.ll.opcode < iJCXZ)))
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -946,7 +946,7 @@ void Function::findIdioms()
|
||||
Int idx; /* Index into local identifier table */
|
||||
byte regH, regL; /* High and low registers for long word reg */
|
||||
|
||||
pIcode = Icode.GetFirstIcode();
|
||||
pIcode = &Icode.front();
|
||||
pEnd = pIcode + Icode.GetNumIcodes();
|
||||
ip = 0;
|
||||
|
||||
@ -1192,10 +1192,8 @@ void Function::findIdioms()
|
||||
case iSUB: /* Idiom 6 */
|
||||
if (idiom6 (pIcode, pEnd))
|
||||
{
|
||||
lhs = COND_EXPR::idLong (&localId, DST, pIcode, LOW_FIRST,
|
||||
ip, USE_DEF, 1);
|
||||
rhs = COND_EXPR::idLong (&localId, SRC, pIcode, LOW_FIRST,
|
||||
ip, eUSE, 1);
|
||||
lhs = COND_EXPR::idLong (&localId, DST, pIcode, LOW_FIRST, ip, USE_DEF, 1);
|
||||
rhs = COND_EXPR::idLong (&localId, SRC, pIcode, LOW_FIRST, ip, eUSE, 1);
|
||||
exp = COND_EXPR::boolOp (lhs, rhs, SUB);
|
||||
pIcode->setAsgn(lhs, exp);
|
||||
(pIcode+1)->invalidate();
|
||||
|
||||
@ -321,16 +321,16 @@ boolT checkLongEq (LONG_STKID_TYPE longId, ICODE *pIcode, Int i, Int idx,
|
||||
if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC)
|
||||
*rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST,
|
||||
idx, eUSE, off);
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
||||
{
|
||||
*lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx,
|
||||
eDEF, off);
|
||||
*rhs = COND_EXPR::idLongIdx (i);
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -358,15 +358,15 @@ boolT checkLongRegEq (LONGID_TYPE longId, ICODE *pIcode, Int i, Int idx,
|
||||
*lhs = COND_EXPR::idLongIdx (i);
|
||||
if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC)
|
||||
*rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, idx, eUSE, off);
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi))
|
||||
{
|
||||
*lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx, eDEF, off);
|
||||
*rhs = COND_EXPR::idLongIdx (i);
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -48,7 +48,9 @@ void parse (CALL_GRAPH * *pcallGraph)
|
||||
state.checkStartup();
|
||||
|
||||
/* Make a struct for the initial procedure */
|
||||
pProcList.resize(1); // default-construct a Function object !
|
||||
|
||||
// default-construct a Function object !
|
||||
pProcList.push_back(Function::Create());
|
||||
if (prog.offMain != -1)
|
||||
{
|
||||
/* We know where main() is. Start the flow of control from there */
|
||||
@ -558,14 +560,14 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps
|
||||
if (pIcode->ic.ll.flg & I)
|
||||
{
|
||||
/* Search procedure list for one with appropriate entry point */
|
||||
std::list<Function>::iterator iter= std::find_if(pProcList.begin(),pProcList.end(),
|
||||
ilFunction iter= std::find_if(pProcList.begin(),pProcList.end(),
|
||||
[pIcode](const Function &f) ->
|
||||
bool { return f.procEntry==pIcode->ic.ll.immed.op; });
|
||||
|
||||
/* Create a new procedure node and save copy of the state */
|
||||
if (iter==pProcList.end())
|
||||
{
|
||||
pProcList.push_back(Function());
|
||||
pProcList.push_back(Function::Create());
|
||||
Function &x(pProcList.back());
|
||||
iter = (++pProcList.rbegin()).base();
|
||||
x.procEntry = pIcode->ic.ll.immed.op;
|
||||
@ -576,7 +578,6 @@ boolT Function::process_CALL (ICODE * pIcode, CALL_GRAPH * pcallGraph, STATE *ps
|
||||
/* A library function. No need to do any more to it */
|
||||
pcallGraph->insertCallGraph (this, iter);
|
||||
iter = (++pProcList.rbegin()).base();
|
||||
|
||||
Icode.GetIcode(ip)->ic.ll.immed.proc.proc = &x;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ boolT CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
|
||||
if (proc == caller)
|
||||
{
|
||||
insertArc (callee);
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -96,7 +96,7 @@ 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 newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
||||
void Function::newRegArg(ICODE *picode, ICODE *ticode)
|
||||
{
|
||||
COND_EXPR *lhs;
|
||||
STKFRAME * ps, *ts;
|
||||
@ -118,7 +118,7 @@ void newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
||||
type = lhs->expr.ident.idType;
|
||||
if (type == REGISTER)
|
||||
{
|
||||
regL = pproc->localId.id_arr[lhs->expr.ident.idNode.regiIdx].id.regi;
|
||||
regL = localId.id_arr[lhs->expr.ident.idNode.regiIdx].id.regi;
|
||||
if (regL < rAL)
|
||||
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
||||
else
|
||||
@ -126,8 +126,8 @@ void newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
||||
}
|
||||
else if (type == LONG_VAR)
|
||||
{
|
||||
regL = pproc->localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l;
|
||||
regH = pproc->localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h;
|
||||
regL = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l;
|
||||
regH = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h;
|
||||
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, 0);
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ void newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
||||
/* Mask off high and low register(s) in picode */
|
||||
switch (type) {
|
||||
case REGISTER:
|
||||
id = &pproc->localId.id_arr[lhs->expr.ident.idNode.regiIdx];
|
||||
id = &localId.id_arr[lhs->expr.ident.idNode.regiIdx];
|
||||
picode->du.def &= maskDuReg[id->id.regi];
|
||||
if (id->id.regi < rAL)
|
||||
newsym.type = TYPE_WORD_SIGN;
|
||||
@ -202,7 +202,7 @@ void newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
||||
newsym.type = TYPE_BYTE_SIGN;
|
||||
break;
|
||||
case LONG_VAR:
|
||||
id = &pproc->localId.id_arr[lhs->expr.ident.idNode.longIdx];
|
||||
id = &localId.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;
|
||||
@ -225,12 +225,13 @@ void allocStkArgs (ICODE *picode, Int num)
|
||||
}
|
||||
|
||||
|
||||
boolT newStkArg (ICODE *picode, COND_EXPR *exp, llIcode opcode, Function * pproc)
|
||||
/* Inserts the new expression (ie. the actual parameter) on the argument
|
||||
* list.
|
||||
* Returns: TRUE if it was a near call that made use of a segment register.
|
||||
* FALSE elsewhere */
|
||||
{ STKFRAME * ps;
|
||||
boolT newStkArg (ICODE *picode, COND_EXPR *exp, llIcode opcode, Function * pproc)
|
||||
{
|
||||
STKFRAME * ps;
|
||||
byte regi;
|
||||
|
||||
/* Check for far procedure call, in which case, references to segment
|
||||
@ -243,9 +244,9 @@ boolT newStkArg (ICODE *picode, COND_EXPR *exp, llIcode opcode, Function * pproc
|
||||
regi = pproc->localId.id_arr[exp->expr.ident.idNode.regiIdx].id.regi;
|
||||
if ((regi >= rES) && (regi <= rDS))
|
||||
if (opcode == iCALLF)
|
||||
return (FALSE);
|
||||
return false;
|
||||
else
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,8 +16,8 @@ static boolT isJCond (llIcode opcode)
|
||||
* high-level conditional jump icodes (iJB..iJG) */
|
||||
{
|
||||
if ((opcode >= iJB) && (opcode <= iJG))
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -26,12 +26,12 @@ static boolT isLong23 (Int i, BB * pbb, ICODE * icode, Int *off, Int *arc)
|
||||
{ BB * t, * e, * obb2;
|
||||
|
||||
if (pbb->nodeType != TWO_BRANCH)
|
||||
return (FALSE);
|
||||
return false;
|
||||
t = pbb->edges[THEN].BBptr;
|
||||
e = pbb->edges[ELSE].BBptr;
|
||||
|
||||
/* Check along the THEN path */
|
||||
if ((t->length == 1) && (t->nodeType == TWO_BRANCH) && (t->numInEdges == 1))
|
||||
if ((t->length == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1))
|
||||
{
|
||||
obb2 = t->edges[THEN].BBptr;
|
||||
if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&
|
||||
@ -39,13 +39,13 @@ static boolT isLong23 (Int i, BB * pbb, ICODE * icode, Int *off, Int *arc)
|
||||
{
|
||||
*off = obb2->start - i;
|
||||
*arc = THEN;
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check along the ELSE path */
|
||||
else if ((e->length == 1) && (e->nodeType == TWO_BRANCH) &&
|
||||
(e->numInEdges == 1))
|
||||
(e->inEdges.size() == 1))
|
||||
{
|
||||
obb2 = e->edges[THEN].BBptr;
|
||||
if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&
|
||||
@ -53,10 +53,10 @@ static boolT isLong23 (Int i, BB * pbb, ICODE * icode, Int *off, Int *arc)
|
||||
{
|
||||
*off = obb2->start - i;
|
||||
*arc = ELSE;
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -68,9 +68,9 @@ static boolT isLong22 (ICODE * pIcode, ICODE * pEnd, Int *off)
|
||||
(isJCond ((pIcode+3)->ic.ll.opcode)))
|
||||
{
|
||||
*off = 2;
|
||||
return (TRUE);
|
||||
return true;
|
||||
}
|
||||
return (FALSE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -101,17 +101,13 @@ static void longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
||||
}
|
||||
);
|
||||
tbb->inEdges.erase(newlast,tbb->inEdges.end());
|
||||
tbb->numInEdges--; /* looses 2 arcs, gains 1 arc */
|
||||
tbb->inEdges.push_back(pbb);
|
||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
||||
tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
|
||||
|
||||
/* Modify in edges of the ELSE basic block */
|
||||
tbb = pbb->edges[ELSE].BBptr;
|
||||
auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
|
||||
assert(iter!=tbb->inEdges.end());
|
||||
tbb->inEdges.erase(iter);
|
||||
tbb->numInEdges--; /* looses 1 arc */
|
||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
||||
tbb->inEdges.erase(iter); /* looses 1 arc */
|
||||
/* Update icode index */
|
||||
(*idx) += 5;
|
||||
}
|
||||
@ -127,9 +123,7 @@ static void longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
||||
/* Modify in edges of target basic block */
|
||||
auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
|
||||
assert(iter!=tbb->inEdges.end());
|
||||
tbb->inEdges.erase(iter);
|
||||
tbb->numInEdges--; /* looses 1 arc */
|
||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
||||
tbb->inEdges.erase(iter); /* looses 1 arc */
|
||||
|
||||
/* Modify in edges of the ELSE basic block */
|
||||
tbb = obb2->edges[ELSE].BBptr;
|
||||
@ -140,9 +134,7 @@ static void longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
||||
}
|
||||
);
|
||||
tbb->inEdges.erase(newlast,tbb->inEdges.end());
|
||||
tbb->numInEdges--; /* looses 2 arcs, gains 1 arc */
|
||||
tbb->inEdges.push_back(pbb);
|
||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
||||
tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
|
||||
|
||||
/* Modify out edge of header basic block */
|
||||
pbb->edges[ELSE].BBptr = tbb;
|
||||
@ -154,7 +146,7 @@ static void longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
||||
/* Create new HLI_JCOND and condition */
|
||||
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+off+1)->ic.ll.opcode-iJB]);
|
||||
(pIcode+1)->setJCond(lhs);
|
||||
copyDU (pIcode+1, pIcode, eUSE, eUSE);
|
||||
(pIcode+1)->copyDU(*pIcode, eUSE, eUSE);
|
||||
(pIcode+1)->du.use |= (pIcode+off)->du.use;
|
||||
|
||||
/* Update statistics */
|
||||
@ -181,7 +173,7 @@ static void longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
||||
/* Form conditional expression */
|
||||
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+3)->ic.ll.opcode - iJB]);
|
||||
(pIcode+1)->setJCond(lhs);
|
||||
copyDU (pIcode+1, pIcode, eUSE, eUSE);
|
||||
(pIcode+1)->copyDU (*pIcode, eUSE, eUSE);
|
||||
(pIcode+1)->du.use |= (pIcode+2)->du.use;
|
||||
|
||||
/* Adjust outEdges[0] to the new target basic block */
|
||||
@ -200,11 +192,8 @@ static void longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
||||
assert(iter!=tbb->inEdges.end());
|
||||
tbb->inEdges.erase(iter);
|
||||
|
||||
if ((pIcode+3)->ic.ll.opcode == iJE)
|
||||
tbb->numInEdges--; /* looses 1 arc */
|
||||
else /* iJNE => replace arc */
|
||||
tbb->inEdges.push_back(pbb);
|
||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
||||
if ((pIcode+3)->ic.ll.opcode != iJE)
|
||||
tbb->inEdges.push_back(pbb); /* iJNE => replace arc */
|
||||
|
||||
/* Modify ELSE out edge of header basic block */
|
||||
tbb = obb1->edges[ELSE].BBptr;
|
||||
@ -215,9 +204,8 @@ static void longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
||||
tbb->inEdges.erase(iter);
|
||||
if ((pIcode+3)->ic.ll.opcode == iJE) /* replace */
|
||||
tbb->inEdges.push_back(pbb);
|
||||
else
|
||||
tbb->numInEdges--; /* iJNE => looses 1 arc */
|
||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
||||
// else
|
||||
// tbb->numInEdges--; /* iJNE => looses 1 arc */
|
||||
|
||||
|
||||
/* Update statistics */
|
||||
@ -493,7 +481,7 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
|
||||
lhs = COND_EXPR::boolOp (lhs, rhs,
|
||||
condOpJCond[(pIcode+1)->ic.ll.opcode - iJB]);
|
||||
(pIcode+1)->setJCond(lhs);
|
||||
copyDU (pIcode+1, pIcode, eUSE, eUSE);
|
||||
(pIcode+1)->copyDU(*pIcode, eUSE, eUSE);
|
||||
pIcode->invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ static void appendNodeInt (queue &pqH, BB *node, interval *pI)
|
||||
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
||||
if(found_iter!=pqH.end())
|
||||
{
|
||||
pI->numOutEdges -= (byte)(*found_iter)->numInEdges - 1;
|
||||
pI->numOutEdges -= (byte)(*found_iter)->inEdges.size() - 1;
|
||||
pqH.erase(found_iter);
|
||||
}
|
||||
}
|
||||
@ -99,7 +99,7 @@ static void appendNodeInt (queue &pqH, BB *node, interval *pI)
|
||||
/* Finds the intervals of graph derivedGi->Gi and places them in the list
|
||||
* of intervals derivedGi->Ii.
|
||||
* Algorithm by M.S.Hecht. */
|
||||
void derSeq_Entry::findIntervals ()
|
||||
void derSeq_Entry::findIntervals (Function *c)
|
||||
{
|
||||
interval *pI, /* Interval being processed */
|
||||
*J; /* ^ last interval in derivedGi->Ii */
|
||||
@ -112,7 +112,7 @@ void derSeq_Entry::findIntervals ()
|
||||
|
||||
appendQueue (H, Gi); /* H = {first node of G} */
|
||||
Gi->beenOnH = TRUE;
|
||||
Gi->reachingInt = BB::Create(); /* ^ empty BB */
|
||||
Gi->reachingInt = BB::Create(0,"",c); /* ^ empty BB */
|
||||
|
||||
/* Process header nodes list H */
|
||||
while (!H.empty())
|
||||
@ -185,10 +185,9 @@ static void displayIntervals (interval *pI)
|
||||
while (nodePtr!=pI->nodes.end())
|
||||
{
|
||||
if ((*nodePtr)->correspInt == NULL) /* real BBs */
|
||||
printf (" Node: %ld\n", (*nodePtr)->start);
|
||||
printf (" Node: %ld\n", (*nodePtr)->begin());
|
||||
else /* BBs represent intervals */
|
||||
printf (" Node (corresp int): %d\n",
|
||||
(*nodePtr)->correspInt->numInt);
|
||||
printf (" Node (corresp int): %d\n", (*nodePtr)->correspInt->numInt);
|
||||
++nodePtr;
|
||||
}
|
||||
pI = pI->next;
|
||||
@ -240,7 +239,7 @@ derSeq_Entry::~derSeq_Entry()
|
||||
|
||||
/* Finds the next order graph of derivedGi->Gi according to its intervals
|
||||
* (derivedGi->Ii), and places it in derivedGi->next->Gi. */
|
||||
static boolT nextOrderGraph (derSeq *derivedGi)
|
||||
bool Function::nextOrderGraph (derSeq *derivedGi)
|
||||
{
|
||||
interval *Ii; /* Interval being processed */
|
||||
BB *BBnode, /* New basic block of intervals */
|
||||
@ -263,7 +262,7 @@ static boolT nextOrderGraph (derSeq *derivedGi)
|
||||
while (Ii)
|
||||
{
|
||||
i = 0;
|
||||
bbs.push_back(BB::Create(-1, -1, INTERVAL_NODE, Ii->numOutEdges, NULL));
|
||||
bbs.push_back(BB::Create(-1, -1, INTERVAL_NODE, Ii->numOutEdges, this));
|
||||
BBnode = bbs.back();
|
||||
BBnode->correspInt = Ii;
|
||||
const queue &listIi(Ii->nodes);
|
||||
@ -307,7 +306,7 @@ static boolT nextOrderGraph (derSeq *derivedGi)
|
||||
if(iter==bbs.end())
|
||||
fatalError (INVALID_INT_BB);
|
||||
edge.BBptr = *iter;
|
||||
(*iter)->numInEdges++;
|
||||
(*iter)->inEdges.push_back(0);
|
||||
(*iter)->inEdgeCount++;
|
||||
}
|
||||
}
|
||||
@ -319,7 +318,7 @@ static boolT nextOrderGraph (derSeq *derivedGi)
|
||||
/* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
|
||||
* Constructs the n-th order graph and places all the intermediate graphs
|
||||
* in the derivedG list sequence. */
|
||||
static byte findDerivedSeq (derSeq *derivedGi)
|
||||
byte Function::findDerivedSeq (derSeq *derivedGi)
|
||||
{
|
||||
BB *Gi; /* Current derived sequence graph */
|
||||
|
||||
@ -328,7 +327,7 @@ static byte findDerivedSeq (derSeq *derivedGi)
|
||||
while (! trivialGraph (Gi))
|
||||
{
|
||||
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
||||
iter->findIntervals ();
|
||||
iter->findIntervals(this);
|
||||
|
||||
/* Create Gi+1 and check if it is equivalent to Gi */
|
||||
if (! nextOrderGraph (derivedGi))
|
||||
@ -346,7 +345,7 @@ static byte findDerivedSeq (derSeq *derivedGi)
|
||||
// derivedGi->next = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
derivedGi->back().findIntervals ();
|
||||
derivedGi->back().findIntervals (this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -126,8 +126,8 @@ static struct {
|
||||
{ none1, none2, OP386 , iZERO , 0 , }, /* 67 */
|
||||
{ data2, none2, NO_SRC , iPUSH , 0 , }, /* 68 */
|
||||
{ modrm, data2, TO_REG | NSP , iIMUL , Sf | Zf | Cf, }, /* 69 */
|
||||
{ data1, none2, S | NO_SRC , iPUSH , 0 , }, /* 6A */
|
||||
{ modrm, data1, TO_REG | NSP | S , iIMUL , Sf | Zf | Cf, }, /* 6B */
|
||||
{ data1, none2, S_EXT | NO_SRC , iPUSH , 0 , }, /* 6A */
|
||||
{ modrm, data1, TO_REG | NSP | S_EXT , iIMUL , Sf | Zf | Cf, }, /* 6B */
|
||||
{ strop, memImp, NOT_HLL | B|IM_OPS , iINS , 0 , Df }, /* 6C */
|
||||
{ strop, memImp, NOT_HLL | IM_OPS , iINS , 0 , Df }, /* 6D */
|
||||
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS , 0 , Df }, /* 6E */
|
||||
@ -151,7 +151,7 @@ static struct {
|
||||
{ immed, data1, B , iZERO , 0 , }, /* 80 */
|
||||
{ immed, data2, NSP , iZERO , 0 , }, /* 81 */
|
||||
{ immed, data1, B , iZERO , 0 , }, /* 82 */ /* ?? */
|
||||
{ immed, data1, NSP | S , iZERO , 0 , }, /* 83 */
|
||||
{ immed, data1, NSP | S_EXT , iZERO , 0 , }, /* 83 */
|
||||
{ modrm, none2, TO_REG | B , iTEST , Sf | Zf | Cf, }, /* 84 */
|
||||
{ modrm, none2, TO_REG | NSP , iTEST , Sf | Zf | Cf, }, /* 85 */
|
||||
{ modrm, none2, TO_REG | B , iXCHG , 0 , }, /* 86 */
|
||||
@ -172,8 +172,8 @@ static struct {
|
||||
{ regop, axImp, 0 , iXCHG , 0 , }, /* 95 */
|
||||
{ regop, axImp, 0 , iXCHG , 0 , }, /* 96 */
|
||||
{ regop, axImp, 0 , iXCHG , 0 , }, /* 97 */
|
||||
{ alImp, axImp, SRC_B | S , iSIGNEX,0 , }, /* 98 */
|
||||
{axSrcIm, axImp, IM_DST | S , iSIGNEX,0 , }, /* 99 */
|
||||
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX,0 , }, /* 98 */
|
||||
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX,0 , }, /* 99 */
|
||||
{ dispF, none2, 0 , iCALLF ,0 , }, /* 9A */
|
||||
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT , 0 , }, /* 9B */
|
||||
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF, 0 , }, /* 9C */
|
||||
@ -658,7 +658,7 @@ static void arith(Int i)
|
||||
*****************************************************************************/
|
||||
static void data1(Int i)
|
||||
{
|
||||
pIcode->ic.ll.immed.op = (stateTable[i].flg & S)? signex(*pInst++):
|
||||
pIcode->ic.ll.immed.op = (stateTable[i].flg & S_EXT)? signex(*pInst++):
|
||||
*pInst++;
|
||||
pIcode->ic.ll.flg |= I;
|
||||
}
|
||||
|
||||
156
src/udm.cpp
156
src/udm.cpp
@ -15,6 +15,54 @@ static void displayDfs(BB * pBB);
|
||||
/****************************************************************************
|
||||
* udm
|
||||
****************************************************************************/
|
||||
void Function::buildCFG()
|
||||
{
|
||||
if(flg & PROC_ISLIB)
|
||||
return; /* Ignore library functions */
|
||||
createCFG();
|
||||
if (option.VeryVerbose)
|
||||
displayCFG();
|
||||
/* Remove redundancies and add in-edge information */
|
||||
compressCFG();
|
||||
|
||||
/* Print 2nd pass assembler listing */
|
||||
if (option.asm2)
|
||||
disassem(2, this);
|
||||
|
||||
/* Idiom analysis and propagation of long type */
|
||||
lowLevelAnalysis();
|
||||
|
||||
/* Generate HIGH_LEVEL icodes whenever possible */
|
||||
highLevelGen();
|
||||
}
|
||||
void Function::controlFlowAnalysis()
|
||||
{
|
||||
if (flg & PROC_ISLIB)
|
||||
return; /* Ignore library functions */
|
||||
derSeq *derivedG=0;
|
||||
|
||||
/* Make cfg reducible and build derived sequences */
|
||||
derivedG=checkReducibility();
|
||||
|
||||
if (option.VeryVerbose)
|
||||
derivedG->display();
|
||||
|
||||
/* Structure the graph */
|
||||
structure(derivedG);
|
||||
|
||||
/* Check for compound conditions */
|
||||
compoundCond ();
|
||||
|
||||
if (option.verbose)
|
||||
{
|
||||
printf("\nDepth first traversal - Proc %s\n", name);
|
||||
cfg.front()->displayDfs();
|
||||
}
|
||||
|
||||
/* Free storage occupied by this procedure */
|
||||
freeDerivedSeq(*derivedG);
|
||||
|
||||
}
|
||||
void udm(void)
|
||||
{
|
||||
|
||||
@ -22,73 +70,21 @@ void udm(void)
|
||||
* icodes to high-level ones */
|
||||
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
|
||||
{
|
||||
|
||||
if (iter->flg & PROC_ISLIB)
|
||||
continue; /* Ignore library functions */
|
||||
|
||||
/* Create the basic control flow graph */
|
||||
iter->createCFG();
|
||||
if (option.VeryVerbose)
|
||||
iter->displayCFG();
|
||||
|
||||
/* Remove redundancies and add in-edge information */
|
||||
iter->compressCFG();
|
||||
|
||||
/* Print 2nd pass assembler listing */
|
||||
if (option.asm2)
|
||||
disassem(2, &(*iter));
|
||||
|
||||
/* Idiom analysis and propagation of long type */
|
||||
iter->lowLevelAnalysis();
|
||||
|
||||
/* Generate HIGH_LEVEL icodes whenever possible */
|
||||
iter->highLevelGen();
|
||||
iter->buildCFG();
|
||||
}
|
||||
|
||||
/* Data flow analysis - eliminate condition codes, extraneous registers
|
||||
* and intermediate instructions. Find expressions by forward
|
||||
* substitution algorithm */
|
||||
pProcList.front().dataFlow (0);
|
||||
derSeq *derivedG=0;
|
||||
|
||||
/* Control flow analysis - structuring algorithm */
|
||||
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
|
||||
{
|
||||
|
||||
if (iter->flg & PROC_ISLIB)
|
||||
continue; /* Ignore library functions */
|
||||
|
||||
/* Make cfg reducible and build derived sequences */
|
||||
derivedG=iter->checkReducibility();
|
||||
|
||||
if (option.VeryVerbose)
|
||||
derivedG->display();
|
||||
|
||||
/* Structure the graph */
|
||||
iter->structure(derivedG);
|
||||
|
||||
/* Check for compound conditions */
|
||||
iter->compoundCond ();
|
||||
|
||||
if (option.verbose) {
|
||||
printf("\nDepth first traversal - Proc %s\n", iter->name);
|
||||
iter->cfg.front()->displayDfs();
|
||||
}
|
||||
|
||||
/* Free storage occupied by this procedure */
|
||||
freeDerivedSeq(*derivedG);
|
||||
iter->controlFlowAnalysis();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *const s_nodeType[] = {"branch", "if", "case", "fall", "return", "call",
|
||||
"loop", "repeat", "interval", "cycleHead",
|
||||
"caseHead", "terminate",
|
||||
"nowhere" };
|
||||
|
||||
static const char *const s_loopType[] = {"noLoop", "while", "repeat", "loop", "for"};
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* displayCFG - Displays the Basic Block list
|
||||
***************************************************************************/
|
||||
@ -102,58 +98,8 @@ void Function::displayCFG()
|
||||
for (auto iter = cfg.begin(); iter!=cfg.end(); ++iter)
|
||||
{
|
||||
pBB = *iter;
|
||||
printf("\nnode type = %s, ", s_nodeType[pBB->nodeType]);
|
||||
printf("start = %ld, length = %ld, #out edges = %ld\n",
|
||||
pBB->start, pBB->length, pBB->numOutEdges);
|
||||
|
||||
for (i = 0; i < pBB->numOutEdges; i++)
|
||||
printf(" outEdge[%2d] = %ld\n",i, pBB->edges[i].BBptr->start);
|
||||
(*iter)->display();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* displayDfs - Displays the CFG using a depth first traversal
|
||||
****************************************************************************/
|
||||
void BB::displayDfs()
|
||||
{
|
||||
Int i;
|
||||
assert(this);
|
||||
traversed = DFS_DISP;
|
||||
|
||||
printf("node type = %s, ", s_nodeType[nodeType]);
|
||||
printf("start = %ld, length = %ld, #in-edges = %ld, #out-edges = %ld\n",
|
||||
start, length, inEdges.size(), numOutEdges);
|
||||
printf("dfsFirst = %ld, dfsLast = %ld, immed dom = %ld\n",
|
||||
dfsFirstNum, dfsLastNum,
|
||||
immedDom == MAX ? -1 : immedDom);
|
||||
printf("loopType = %s, loopHead = %ld, latchNode = %ld, follow = %ld\n",
|
||||
s_loopType[loopType],
|
||||
loopHead == MAX ? -1 : loopHead,
|
||||
latchNode == MAX ? -1 : latchNode,
|
||||
loopFollow == MAX ? -1 : loopFollow);
|
||||
printf ("ifFollow = %ld, caseHead = %ld, caseTail = %ld\n",
|
||||
ifFollow == MAX ? -1 : ifFollow,
|
||||
caseHead == MAX ? -1 : caseHead,
|
||||
caseTail == MAX ? -1 : caseTail);
|
||||
|
||||
if (nodeType == INTERVAL_NODE)
|
||||
printf("corresponding interval = %ld\n", correspInt->numInt);
|
||||
else
|
||||
for (i = 0; i < inEdges.size(); i++)
|
||||
printf (" inEdge[%ld] = %ld\n", i, inEdges[i]->start);
|
||||
|
||||
/* Display out edges information */
|
||||
for (i = 0; i < numOutEdges; i++)
|
||||
if (nodeType == INTERVAL_NODE)
|
||||
printf(" outEdge[%ld] = %ld\n", i,
|
||||
edges[i].BBptr->correspInt->numInt);
|
||||
else
|
||||
printf(" outEdge[%d] = %ld\n", i, edges[i].BBptr->start);
|
||||
printf("----\n");
|
||||
|
||||
/* Recursive call on successors of current node */
|
||||
for (i = 0; i < numOutEdges; i++)
|
||||
if (edges[i].BBptr->traversed != DFS_DISP)
|
||||
edges[i].BBptr->displayDfs();
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include "dcc.h"
|
||||
|
||||
|
||||
long LMOD@ (long arg0, int arg2int arg3)
|
||||
long LMOD@ (long arg0, int arg2, int arg3)
|
||||
/* Takes 8 bytes of parameters.
|
||||
* Runtime support routine of the compiler.
|
||||
* Untranslatable routine. Assembler provided.
|
||||
|
||||
0
tests/prev/BENCHFN.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHFN.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHFN.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHFN.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHFN.b
Executable file → Normal file
0
tests/prev/BENCHFN.b
Executable file → Normal file
0
tests/prev/BENCHLNG.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHLNG.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHLNG.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHLNG.EXE.a2
Executable file → Normal file
2
tests/prev/BENCHLNG.b
Executable file → Normal file
2
tests/prev/BENCHLNG.b
Executable file → Normal file
@ -6,7 +6,7 @@
|
||||
#include "dcc.h"
|
||||
|
||||
|
||||
long LMOD@ (long arg0, int arg2int arg3)
|
||||
long LMOD@ (long arg0, int arg2, int arg3)
|
||||
/* Takes 8 bytes of parameters.
|
||||
* Runtime support routine of the compiler.
|
||||
* Untranslatable routine. Assembler provided.
|
||||
|
||||
0
tests/prev/BENCHMUL.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHMUL.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHMUL.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHMUL.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHMUL.b
Executable file → Normal file
0
tests/prev/BENCHMUL.b
Executable file → Normal file
0
tests/prev/BENCHMUS.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHMUS.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHMUS.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHMUS.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHMUS.b
Executable file → Normal file
0
tests/prev/BENCHMUS.b
Executable file → Normal file
0
tests/prev/BENCHSHO.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHSHO.EXE.a1
Executable file → Normal file
0
tests/prev/BENCHSHO.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHSHO.EXE.a2
Executable file → Normal file
0
tests/prev/BENCHSHO.b
Executable file → Normal file
0
tests/prev/BENCHSHO.b
Executable file → Normal file
0
tests/prev/BYTEOPS.EXE.a1
Executable file → Normal file
0
tests/prev/BYTEOPS.EXE.a1
Executable file → Normal file
0
tests/prev/BYTEOPS.EXE.a2
Executable file → Normal file
0
tests/prev/BYTEOPS.EXE.a2
Executable file → Normal file
0
tests/prev/BYTEOPS.b
Executable file → Normal file
0
tests/prev/BYTEOPS.b
Executable file → Normal file
0
tests/prev/FIBOS.EXE.a1
Executable file → Normal file
0
tests/prev/FIBOS.EXE.a1
Executable file → Normal file
0
tests/prev/FIBOS.EXE.a2
Executable file → Normal file
0
tests/prev/FIBOS.EXE.a2
Executable file → Normal file
0
tests/prev/FIBOS.b
Executable file → Normal file
0
tests/prev/FIBOS.b
Executable file → Normal file
0
tests/prev/MIN.EXE.a1
Executable file → Normal file
0
tests/prev/MIN.EXE.a1
Executable file → Normal file
0
tests/prev/MIN.EXE.a2
Executable file → Normal file
0
tests/prev/MIN.EXE.a2
Executable file → Normal file
0
tests/prev/MIN.b
Executable file → Normal file
0
tests/prev/MIN.b
Executable file → Normal file
Loading…
x
Reference in New Issue
Block a user