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)
|
PROJECT(dcc_original)
|
||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
SET(CMAKE_BUILD_TYPE Debug)
|
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS)
|
||||||
INCLUDE_DIRECTORIES(include ${Boost_INCLUDE_DIRS})
|
|
||||||
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||||
add_definitions(/W4)
|
add_definitions(/W4)
|
||||||
else()
|
else()
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x")
|
||||||
|
SET(CMAKE_CXX_FLAGS_DEBUG "-D_GLIBCXX_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}" )
|
||||||
endif()
|
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
|
set(dcc_SOURCES
|
||||||
src/dcc.cpp
|
src/dcc.cpp
|
||||||
src/ast.cpp
|
src/ast.cpp
|
||||||
@ -60,4 +68,5 @@ set(dcc_HEADERS
|
|||||||
include/BasicBlock.h
|
include/BasicBlock.h
|
||||||
)
|
)
|
||||||
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
||||||
|
TARGET_LINK_LIBRARIES(dcc_original ${REQ_LLVM_LIBRARIES})
|
||||||
|
|
||||||
|
|||||||
@ -2,12 +2,16 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <llvm/ADT/ilist.h>
|
||||||
|
#include <llvm/ADT/ilist_node.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "graph.h"
|
||||||
/* Basic block (BB) node definition */
|
/* Basic block (BB) node definition */
|
||||||
struct Function;
|
struct Function;
|
||||||
class CIcodeRec;
|
class CIcodeRec;
|
||||||
struct BB;
|
struct BB;
|
||||||
struct interval;
|
struct interval;
|
||||||
|
struct ICODE;
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
dword ip; /* Out edge icode address */
|
dword ip; /* Out edge icode address */
|
||||||
@ -15,13 +19,13 @@ typedef union
|
|||||||
interval *intPtr; /* Out edge ptr to next interval*/
|
interval *intPtr; /* Out edge ptr to next interval*/
|
||||||
} TYPEADR_TYPE;
|
} TYPEADR_TYPE;
|
||||||
|
|
||||||
struct BB
|
struct BB : public llvm::ilist_node<BB>
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
BB(const BB&);
|
BB(const BB&);
|
||||||
BB() : nodeType(0),traversed(0),start(0),length(0),
|
BB() : nodeType(0),traversed(0),start(0),length(0),
|
||||||
numHlIcodes(0),flg(0),
|
numHlIcodes(0),flg(0),
|
||||||
numInEdges(0),inEdges(0),
|
inEdges(0),
|
||||||
numOutEdges(0),edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
numOutEdges(0),edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
|
||||||
inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(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),
|
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:
|
public:
|
||||||
|
Int begin();
|
||||||
|
Int end();
|
||||||
|
Int rbegin();
|
||||||
|
Int rend();
|
||||||
|
ICODE &front();
|
||||||
|
ICODE &back();
|
||||||
|
size_t size();
|
||||||
byte nodeType; /* Type of node */
|
byte nodeType; /* Type of node */
|
||||||
Int traversed; /* Boolean: traversed yet? */
|
int traversed; /* Boolean: traversed yet? */
|
||||||
Int start; /* First instruction offset */
|
Int start; /* First instruction offset */
|
||||||
Int length; /* No. of instructions this BB */
|
Int length; /* No. of instructions this BB */
|
||||||
Int numHlIcodes; /* No. of high-level icodes */
|
Int numHlIcodes; /* No. of high-level icodes */
|
||||||
flags32 flg; /* BB flags */
|
flags32 flg; /* BB flags */
|
||||||
|
|
||||||
/* In edges and out edges */
|
/* In edges and out edges */
|
||||||
Int numInEdges; /* Number of in edges */
|
|
||||||
std::vector<BB *> inEdges; // does not own held pointers
|
std::vector<BB *> inEdges; // does not own held pointers
|
||||||
|
|
||||||
Int numOutEdges; /* Number of out edges */
|
Int numOutEdges; /* Number of out edges */
|
||||||
@ -81,8 +93,17 @@ public:
|
|||||||
Int index; /* Index, used in several ways */
|
Int index; /* Index, used in several ways */
|
||||||
static BB *Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
|
static BB *Create(void *ctx=0,const std::string &s="",Function *parent=0,BB *insertBefore=0);
|
||||||
static BB *Create(Int start, Int ip, byte nodeType, Int numOutEdges, Function * parent);
|
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 writeCode(Int indLevel, Function *pProc, Int *numLoc, Int latchNode, Int ifFollow);
|
||||||
void mergeFallThrough(CIcodeRec &Icode);
|
void mergeFallThrough(CIcodeRec &Icode);
|
||||||
void dfsNumbering(std::vector<BB *> &dfsLast, Int *first, Int *last);
|
void dfsNumbering(std::vector<BB *> &dfsLast, Int *first, Int *last);
|
||||||
void displayDfs();
|
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
|
#pragma once
|
||||||
|
#include <llvm/ADT/ilist.h>
|
||||||
|
#include <llvm/ADT/ilist_node.h>
|
||||||
|
#include "BasicBlock.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
@ -9,8 +12,44 @@
|
|||||||
#include "StackFrame.h"
|
#include "StackFrame.h"
|
||||||
/* PROCEDURE NODE */
|
/* PROCEDURE NODE */
|
||||||
struct CALL_GRAPH;
|
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 */
|
dword procEntry; /* label number */
|
||||||
char name[SYMLEN]; /* Meaningful name for this proc */
|
char name[SYMLEN]; /* Meaningful name for this proc */
|
||||||
STATE state; /* Entry state */
|
STATE state; /* Entry state */
|
||||||
@ -36,15 +75,16 @@ struct Function
|
|||||||
dword liveOut; /* Registers that may be used in successors */
|
dword liveOut; /* Registers that may be used in successors */
|
||||||
boolT liveAnal; /* Procedure has been analysed already */
|
boolT liveAnal; /* Procedure has been analysed already */
|
||||||
|
|
||||||
/* Double-linked list */
|
Function(void *ty=0) : procEntry(0),depth(0),flg(0),cbParam(0),cfg(0),dfsLast(0),numBBs(0),
|
||||||
// Function *next;
|
|
||||||
// Function *prev;
|
|
||||||
public:
|
|
||||||
Function() : 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)
|
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
|
||||||
{
|
{
|
||||||
memset(name,0,SYMLEN);
|
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 compoundCond();
|
||||||
void writeProcComments();
|
void writeProcComments();
|
||||||
void lowLevelAnalysis();
|
void lowLevelAnalysis();
|
||||||
@ -66,7 +106,13 @@ public:
|
|||||||
void codeGen(std::ostream &fs);
|
void codeGen(std::ostream &fs);
|
||||||
void displayStats();
|
void displayStats();
|
||||||
void mergeFallThrough(BB *pBB);
|
void mergeFallThrough(BB *pBB);
|
||||||
|
void structIfs();
|
||||||
|
void structLoops(derSeq *derivedG);
|
||||||
|
void buildCFG();
|
||||||
|
void controlFlowAnalysis();
|
||||||
|
void newRegArg(ICODE *picode, ICODE *ticode);
|
||||||
protected:
|
protected:
|
||||||
|
void structCases();
|
||||||
void findExps();
|
void findExps();
|
||||||
void genDU1();
|
void genDU1();
|
||||||
void elimCondCodes();
|
void elimCondCodes();
|
||||||
@ -74,4 +120,6 @@ protected:
|
|||||||
void findIdioms();
|
void findIdioms();
|
||||||
void propLong();
|
void propLong();
|
||||||
void genLiveKtes();
|
void genLiveKtes();
|
||||||
|
byte findDerivedSeq (derSeq *derivedGi);
|
||||||
|
bool nextOrderGraph(derSeq *derivedGi);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
* (C) Cristina Cifuentes, Mike van Emmerik
|
* (C) Cristina Cifuentes, Mike van Emmerik
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <llvm/ADT/ilist.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
@ -13,8 +13,11 @@
|
|||||||
#include "bundle.h"
|
#include "bundle.h"
|
||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
#include "BasicBlock.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 */
|
/* SYMBOL TABLE */
|
||||||
struct SYM {
|
struct SYM {
|
||||||
@ -50,7 +53,8 @@ public:
|
|||||||
void insertArc(ilFunction newProc);
|
void insertArc(ilFunction newProc);
|
||||||
};
|
};
|
||||||
#define NUM_PROCS_DELTA 5 /* delta # procs a proc invokes */
|
#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 CALL_GRAPH * callGraph; /* Pointer to the head of the call graph */
|
||||||
extern bundle cCode; /* Output C procedure's declaration and code */
|
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 */
|
/* Exported functions from procs.c */
|
||||||
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
|
boolT insertCallGraph (CALL_GRAPH *, ilFunction, ilFunction);
|
||||||
void newRegArg (Function *, ICODE *, ICODE *);
|
|
||||||
boolT newStkArg (ICODE *, COND_EXPR *, llIcode, Function *);
|
boolT newStkArg (ICODE *, COND_EXPR *, llIcode, Function *);
|
||||||
void allocStkArgs (ICODE *, Int);
|
void allocStkArgs (ICODE *, Int);
|
||||||
void placeStkArg (ICODE *, COND_EXPR *, 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 *);
|
std::string walkCondExpr (const COND_EXPR *exp, Function * pProc, Int *);
|
||||||
Int hlTypeSize (const COND_EXPR *, Function *);
|
Int hlTypeSize (const COND_EXPR *, Function *);
|
||||||
hlType expType (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 insertSubTreeReg (COND_EXPR *, COND_EXPR **, byte, LOCAL_ID *);
|
||||||
boolT insertSubTreeLongReg (COND_EXPR *, COND_EXPR **, Int);
|
boolT insertSubTreeLongReg (COND_EXPR *, COND_EXPR **, Int);
|
||||||
//COND_EXPR *concatExps (SEQ_COND_EXPR *, COND_EXPR *, condNodeType);
|
//COND_EXPR *concatExps (SEQ_COND_EXPR *, COND_EXPR *, condNodeType);
|
||||||
@ -202,7 +204,6 @@ Int numElemExpStk();
|
|||||||
boolT emptyExpStk();
|
boolT emptyExpStk();
|
||||||
|
|
||||||
/* Exported functions from hlicode.c */
|
/* Exported functions from hlicode.c */
|
||||||
boolT removeDefRegi (byte, ICODE *, Int, LOCAL_ID *);
|
|
||||||
std::string writeCall (Function *, STKFRAME *, Function *, Int *);
|
std::string writeCall (Function *, STKFRAME *, Function *, Int *);
|
||||||
char *write1HlIcode (HLTYPE, Function *, Int *);
|
char *write1HlIcode (HLTYPE, Function *, Int *);
|
||||||
char *writeJcond (HLTYPE, Function *, Int *);
|
char *writeJcond (HLTYPE, Function *, Int *);
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
struct Function;
|
||||||
/* Types of basic block nodes */
|
/* Types of basic block nodes */
|
||||||
/* Real basic blocks: type defined according to their out-edges */
|
/* Real basic blocks: type defined according to their out-edges */
|
||||||
enum eBBKind
|
enum eBBKind
|
||||||
@ -88,7 +89,7 @@ struct derSeq_Entry
|
|||||||
}
|
}
|
||||||
~derSeq_Entry();
|
~derSeq_Entry();
|
||||||
public:
|
public:
|
||||||
void findIntervals();
|
void findIntervals(Function *c);
|
||||||
};
|
};
|
||||||
class derSeq : public std::list<derSeq_Entry>
|
class derSeq : public std::list<derSeq_Entry>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
//enum condId;
|
//enum condId;
|
||||||
|
struct LOCAL_ID;
|
||||||
/* LOW_LEVEL icode flags */
|
/* LOW_LEVEL icode flags */
|
||||||
enum eLLFlags
|
enum eLLFlags
|
||||||
{
|
{
|
||||||
@ -45,16 +45,19 @@ enum eLLFlags
|
|||||||
|
|
||||||
/* Parser flags */
|
/* Parser flags */
|
||||||
#define TO_REG 0x000100 /* rm is source */
|
#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 OP386 0x000400 /* 386 op-code */
|
||||||
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
#define NSP 0x000800 /* NOT_HLL if SP is src or dst */
|
||||||
#define ICODEMASK 0xFF00FF /* Masks off parser flags */
|
#define ICODEMASK 0xFF00FF /* Masks off parser flags */
|
||||||
|
|
||||||
/* LOW_LEVEL icode, DU flag bits */
|
/* LOW_LEVEL icode, DU flag bits */
|
||||||
#define Cf 1
|
enum eDuFlags
|
||||||
#define Sf 2
|
{
|
||||||
#define Zf 4
|
Cf=1,
|
||||||
#define Df 8
|
Sf=2,
|
||||||
|
Zf=4,
|
||||||
|
Df=8
|
||||||
|
};
|
||||||
|
|
||||||
/* Machine registers */
|
/* Machine registers */
|
||||||
#define rAX 1 /* These are numbered relative to real 8086 */
|
#define rAX 1 /* These are numbered relative to real 8086 */
|
||||||
@ -227,7 +230,7 @@ typedef enum {
|
|||||||
HLI_RET, /* Return from procedure */
|
HLI_RET, /* Return from procedure */
|
||||||
/* pseudo high-level icodes */
|
/* pseudo high-level icodes */
|
||||||
HLI_POP, /* Pop expression */
|
HLI_POP, /* Pop expression */
|
||||||
HLI_PUSH, /* Push expression */
|
HLI_PUSH /* Push expression */
|
||||||
} hlIcode;
|
} hlIcode;
|
||||||
|
|
||||||
/* Def/use of flags - low 4 bits represent flags */
|
/* 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_REGS_DEF 2 /* 2 regs def'd for long-reg vars */
|
||||||
#define MAX_USES 5
|
#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 */
|
/* LOW_LEVEL icode operand record */
|
||||||
struct ICODEMEM
|
struct ICODEMEM
|
||||||
@ -312,6 +308,12 @@ typedef struct
|
|||||||
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */
|
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */
|
||||||
struct ICODE
|
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 */
|
icodeType type; /* Icode type */
|
||||||
boolT invalid; /* Has no HIGH_LEVEL equivalent */
|
boolT invalid; /* Has no HIGH_LEVEL equivalent */
|
||||||
BB *inBB; /* BB to which this icode belongs */
|
BB *inBB; /* BB to which this icode belongs */
|
||||||
@ -323,6 +325,13 @@ struct ICODE
|
|||||||
HLTYPE hl; /* For HIGH_LEVEL icodes */
|
HLTYPE hl; /* For HIGH_LEVEL icodes */
|
||||||
};
|
};
|
||||||
IC ic;/* intermediate code */
|
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 writeIntComment(char *s);
|
||||||
void setRegDU(byte regi, operDu du_in);
|
void setRegDU(byte regi, operDu du_in);
|
||||||
void invalidate();
|
void invalidate();
|
||||||
@ -333,7 +342,10 @@ struct ICODE
|
|||||||
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs); // set this icode to be an assign
|
void setAsgn(COND_EXPR *lhs, COND_EXPR *rhs); // set this icode to be an assign
|
||||||
void setUnary(hlIcode op, COND_EXPR *exp);
|
void setUnary(hlIcode op, COND_EXPR *exp);
|
||||||
void setJCond(COND_EXPR *cexp);
|
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.
|
// This is the icode array object.
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "icode.h"
|
||||||
/* Type definition */
|
/* Type definition */
|
||||||
struct IDX_ARRAY : public std::vector<int>
|
struct IDX_ARRAY : public std::vector<int>
|
||||||
{
|
{
|
||||||
@ -111,7 +112,9 @@ struct LOCAL_ID
|
|||||||
std::vector<ID> id_arr;
|
std::vector<ID> id_arr;
|
||||||
public:
|
public:
|
||||||
LOCAL_ID()
|
LOCAL_ID()
|
||||||
{}
|
{
|
||||||
|
id_arr.reserve(256);
|
||||||
|
}
|
||||||
Int newByteWordReg(hlType t, byte regi);
|
Int newByteWordReg(hlType t, byte regi);
|
||||||
Int newByteWordStk(hlType t, Int off, byte regOff);
|
Int newByteWordStk(hlType t, Int off, byte regOff);
|
||||||
Int newIntIdx(int16 seg, int16 off, byte regi, Int ix, hlType t);
|
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 */
|
/* 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 */
|
/* 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 */
|
/* Macro tests bit b for type t in prog.map */
|
||||||
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
|
#define BITMAP(b, t) (prog.map[(b) >> 2] & ((t) << (((b) & 3) << 1)))
|
||||||
|
|||||||
@ -1,9 +1,16 @@
|
|||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "BasicBlock.h"
|
#include "BasicBlock.h"
|
||||||
#include "Procedure.h"
|
#include "Procedure.h"
|
||||||
#include "dcc.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)
|
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->Icode.SetInBB(start, ip, pnewBB);
|
||||||
parent->heldBBs.push_back(pnewBB);
|
parent->heldBBs.push_back(pnewBB);
|
||||||
parent->cfg.push_back(pnewBB);
|
parent->cfg.push_back(pnewBB);
|
||||||
|
pnewBB->Parent = parent;
|
||||||
}
|
}
|
||||||
if (start != -1) /* Only for code BB's */
|
if (start != -1) /* Only for code BB's */
|
||||||
stats.numBBbef++;
|
stats.numBBbef++;
|
||||||
return pnewBB;
|
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 */
|
/* 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);
|
// 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:
|
case eDEF:
|
||||||
if (duDu == eDEF)
|
if (duDu == eDEF)
|
||||||
pIcode->du.def=duIcode->du.def;
|
du.def=duIcode.du.def;
|
||||||
else
|
else
|
||||||
pIcode->du.def=duIcode->du.use;
|
du.def=duIcode.du.use;
|
||||||
break;
|
break;
|
||||||
case eUSE:
|
case eUSE:
|
||||||
if (duDu == eDEF)
|
if (duDu == eDEF)
|
||||||
pIcode->du.use=duIcode->du.def;
|
du.use=duIcode.du.def;
|
||||||
else
|
else
|
||||||
pIcode->du.use =duIcode->du.use;
|
du.use =duIcode.du.use;
|
||||||
break;
|
break;
|
||||||
case USE_DEF:
|
case USE_DEF:
|
||||||
pIcode->du = duIcode->du;
|
du = duIcode.du;
|
||||||
break;
|
break;
|
||||||
case NONE:
|
case NONE:
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
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 */
|
/* Indentation according to the depth of the statement */
|
||||||
static char *indent (Int indLevel)
|
char *indent (Int indLevel)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
return (&indentBuf[indSize-(indLevel*4)-1]);
|
return (&indentBuf[indSize-(indLevel*4)-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Int getNextLabel()
|
|
||||||
/* Returns a unique index to the next label */
|
/* 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++);
|
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!
|
// Note: Not currently called!
|
||||||
static void emitFwdGotoLabel (ICODE * pt, Int indLevel)
|
|
||||||
/* Checks the given icode to determine whether it has a label associated
|
/* 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
|
* to it. If so, a goto is emitted to this label; otherwise, a new label
|
||||||
* is created and a goto is also emitted.
|
* is created and a goto is also emitted.
|
||||||
* Note: this procedure is to be used when the label is to be forward on
|
* 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. */
|
* 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 */
|
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,
|
/* Writes the procedure's declaration (including arguments), local variables,
|
||||||
* and invokes the procedure that writes the code of the given record *hli */
|
* and invokes the procedure that writes the code of the given record *hli */
|
||||||
void Function::codeGen (std::ostream &fs)
|
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);
|
sprintf (arg,"%s %s",hlTypes[args.sym[i].type], args.sym[i].name);
|
||||||
strcat (buf, arg);
|
strcat (buf, arg);
|
||||||
if (i < (args.numArgs - 1))
|
if (i < (args.sym.size() - 1))
|
||||||
strcat (buf, ", ");
|
strcat (buf, ", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -581,8 +309,7 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
pBB = dfsLast[i];
|
pBB = dfsLast[i];
|
||||||
if (pBB->flg & INVALID_BB) continue; /* skip invalid BBs */
|
if (pBB->flg & INVALID_BB) continue; /* skip invalid BBs */
|
||||||
printf ("BB %d\n", i);
|
printf ("BB %d\n", i);
|
||||||
printf (" Start = %d, end = %d\n", pBB->start, pBB->start +
|
printf (" Start = %d, end = %d\n", pBB->begin(), pBB->end());
|
||||||
pBB->length - 1);
|
|
||||||
printf (" LiveUse = ");
|
printf (" LiveUse = ");
|
||||||
writeBitVector (pBB->liveUse);
|
writeBitVector (pBB->liveUse);
|
||||||
printf ("\n Def = ");
|
printf ("\n Def = ");
|
||||||
|
|||||||
@ -505,7 +505,8 @@ boolT LibCheck(Function & pProc)
|
|||||||
/*** other types are not considered yet ***/
|
/*** 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)
|
else if (i == NIL)
|
||||||
@ -707,7 +708,7 @@ void STATE::checkStartup()
|
|||||||
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainCompact,
|
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainCompact,
|
||||||
sizeof(pattMainCompact), &i))
|
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.offMain = i+OFFMAINCOMPACT+2+rel; /* Save absolute image offset */
|
||||||
prog.segMain = prog.initCS;
|
prog.segMain = prog.initCS;
|
||||||
chModel = 'c'; /* Compact model */
|
chModel = 'c'; /* Compact model */
|
||||||
@ -724,14 +725,14 @@ void STATE::checkStartup()
|
|||||||
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainSmall,
|
else if (locatePattern(prog.Image, startOff, startOff+0x180, pattMainSmall,
|
||||||
sizeof(pattMainSmall), &i))
|
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.offMain = i+OFFMAINSMALL+2+rel; /* Save absolute image offset */
|
||||||
prog.segMain = prog.initCS;
|
prog.segMain = prog.initCS;
|
||||||
chModel = 's'; /* Small model */
|
chModel = 's'; /* Small model */
|
||||||
}
|
}
|
||||||
else if (memcmp(&prog.Image[startOff], pattTPasStart, sizeof(pattTPasStart)) == 0)
|
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 = rel+startOff+3; /* Save absolute image offset */
|
||||||
prog.offMain += 0x20; /* These first 32 bytes are setting up */
|
prog.offMain += 0x20; /* These first 32 bytes are setting up */
|
||||||
prog.segMain = prog.initCS;
|
prog.segMain = prog.initCS;
|
||||||
|
|||||||
357
src/control.cpp
357
src/control.cpp
@ -35,15 +35,15 @@ static boolT isBackEdge (BB * p,BB * s)
|
|||||||
if (p->dfsFirstNum >= s->dfsFirstNum)
|
if (p->dfsFirstNum >= s->dfsFirstNum)
|
||||||
{
|
{
|
||||||
s->numBackEdges++;
|
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
|
/* Finds the common dominator of the current immediate dominator
|
||||||
* currImmDom and its predecessor's immediate dominator predImmDom */
|
* currImmDom and its predecessor's immediate dominator predImmDom */
|
||||||
|
static Int commonDom (Int currImmDom, Int predImmDom, Function * pProc)
|
||||||
{
|
{
|
||||||
if (currImmDom == NO_DOM)
|
if (currImmDom == NO_DOM)
|
||||||
return (predImmDom);
|
return (predImmDom);
|
||||||
@ -82,8 +82,7 @@ void Function::findImmedDom ()
|
|||||||
BB* inedge=currNode->inEdges[j];
|
BB* inedge=currNode->inEdges[j];
|
||||||
predIdx = inedge->dfsLastNum;
|
predIdx = inedge->dfsLastNum;
|
||||||
if (predIdx < currIdx)
|
if (predIdx < currIdx)
|
||||||
currNode->immedDom = commonDom (currNode->immedDom,
|
currNode->immedDom = commonDom (currNode->immedDom, predIdx, this);
|
||||||
predIdx, this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,7 +182,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
||||||
else
|
else
|
||||||
head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
|
head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
|
||||||
pProc->Icode.SetLlFlag(latchNode->start + latchNode->length - 1,JX_LOOP);
|
latchNode->back().SetLlFlag(JX_LOOP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -192,7 +191,7 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
head->loopFollow = head->edges[ELSE].BBptr->dfsLastNum;
|
head->loopFollow = head->edges[ELSE].BBptr->dfsLastNum;
|
||||||
else
|
else
|
||||||
head->loopFollow = head->edges[THEN].BBptr->dfsLastNum;
|
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 */
|
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;
|
head->loopFollow = latchNode->edges[ELSE].BBptr->dfsLastNum;
|
||||||
else
|
else
|
||||||
head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
|
head->loopFollow = latchNode->edges[THEN].BBptr->dfsLastNum;
|
||||||
pProc->Icode.SetLlFlag(latchNode->start + latchNode->length - 1,
|
latchNode->back().SetLlFlag(JX_LOOP);
|
||||||
JX_LOOP);
|
|
||||||
}
|
}
|
||||||
else /* latch = 1-way */
|
else /* latch = 1-way */
|
||||||
if (latchNode->nodeType == LOOP_NODE)
|
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)
|
if (pbb->dfsLastNum > head->dfsLastNum)
|
||||||
pProc->dfsLast[head->loopFollow]->loopHead = NO_NODE; /*****/
|
pProc->dfsLast[head->loopFollow]->loopHead = NO_NODE; /*****/
|
||||||
pProc->Icode.SetLlFlag(head->start + head->length - 1, JX_LOOP);
|
head->back().SetLlFlag(JX_LOOP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -252,7 +250,6 @@ static void findNodesInLoop(BB * latchNode,BB * head,Function * pProc,queue &int
|
|||||||
freeList(loopNodes);
|
freeList(loopNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//static void findNodesInInt (queue **intNodes, Int level, interval *Ii)
|
//static void findNodesInInt (queue **intNodes, Int level, interval *Ii)
|
||||||
/* Recursive procedure to find nodes that belong to the interval (ie. nodes
|
/* Recursive procedure to find nodes that belong to the interval (ie. nodes
|
||||||
* from G1). */
|
* from G1). */
|
||||||
@ -272,7 +269,7 @@ static void findNodesInInt (queue &intNodes, Int level, interval *Ii)
|
|||||||
|
|
||||||
|
|
||||||
/* Algorithm for structuring loops */
|
/* Algorithm for structuring loops */
|
||||||
static void structLoops(Function * pProc, derSeq *derivedG)
|
void Function::structLoops(derSeq *derivedG)
|
||||||
{
|
{
|
||||||
interval *Ii;
|
interval *Ii;
|
||||||
BB * intHead, /* interval header node */
|
BB * intHead, /* interval header node */
|
||||||
@ -305,7 +302,6 @@ static void structLoops(Function * pProc, derSeq *derivedG)
|
|||||||
findNodesInInt (intNodes, level, Ii);
|
findNodesInInt (intNodes, level, Ii);
|
||||||
|
|
||||||
/* Find greatest enclosing back edge (if any) */
|
/* Find greatest enclosing back edge (if any) */
|
||||||
assert(intHead->numInEdges==intHead->inEdges.size());
|
|
||||||
for (i = 0; i < intHead->inEdges.size(); i++)
|
for (i = 0; i < intHead->inEdges.size(); i++)
|
||||||
{
|
{
|
||||||
pred = intHead->inEdges[i];
|
pred = intHead->inEdges[i];
|
||||||
@ -329,7 +325,7 @@ static void structLoops(Function * pProc, derSeq *derivedG)
|
|||||||
(latchNode->loopHead == NO_NODE))
|
(latchNode->loopHead == NO_NODE))
|
||||||
{
|
{
|
||||||
intHead->latchNode = latchNode->dfsLastNum;
|
intHead->latchNode = latchNode->dfsLastNum;
|
||||||
findNodesInLoop(latchNode, intHead, pProc, intNodes);
|
findNodesInLoop(latchNode, intHead, this, intNodes);
|
||||||
latchNode->flg |= IS_LATCH_NODE;
|
latchNode->flg |= IS_LATCH_NODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,8 +348,8 @@ static boolT successor (Int s, Int h, Function * pProc)
|
|||||||
header = pProc->dfsLast[h];
|
header = pProc->dfsLast[h];
|
||||||
for (i = 0; i < header->numOutEdges; i++)
|
for (i = 0; i < header->numOutEdges; i++)
|
||||||
if (header->edges[i].BBptr->dfsLastNum == s)
|
if (header->edges[i].BBptr->dfsLastNum == s)
|
||||||
return (TRUE);
|
return true;
|
||||||
return (FALSE);
|
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
|
/* Structures case statements. This procedure is invoked only when pProc
|
||||||
* has a case node. */
|
* has a case node. */
|
||||||
{ Int i, j;
|
void Function::structCases()
|
||||||
|
{
|
||||||
|
Int i, j;
|
||||||
BB * caseHeader; /* case header node */
|
BB * caseHeader; /* case header node */
|
||||||
Int exitNode = NO_NODE; /* case exit node */
|
Int exitNode = NO_NODE; /* case exit node */
|
||||||
nodeList caseNodes; /* temporary: list of nodes in case */
|
nodeList caseNodes; /* temporary: list of nodes in case */
|
||||||
|
|
||||||
/* Linear scan of the nodes in reverse dfsLast order, searching for
|
/* Linear scan of the nodes in reverse dfsLast order, searching for
|
||||||
* case nodes */
|
* case nodes */
|
||||||
for (i = pProc->numBBs - 1; i >= 0; i--)
|
for (i = numBBs - 1; i >= 0; i--)
|
||||||
if (pProc->dfsLast[i]->nodeType == MULTI_BRANCH)
|
if (dfsLast[i]->nodeType == MULTI_BRANCH)
|
||||||
{
|
{
|
||||||
caseHeader = pProc->dfsLast[i];
|
caseHeader = dfsLast[i];
|
||||||
|
|
||||||
/* Find descendant node which has as immediate predecessor
|
/* Find descendant node which has as immediate predecessor
|
||||||
* the current header node, and is not a successor. */
|
* 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)) &&
|
if ((!successor(j, i, this)) &&
|
||||||
(pProc->dfsLast[j]->immedDom == i))
|
(dfsLast[j]->immedDom == i))
|
||||||
if (exitNode == NO_NODE)
|
if (exitNode == NO_NODE)
|
||||||
exitNode = j;
|
exitNode = j;
|
||||||
else if (pProc->dfsLast[exitNode]->numInEdges <
|
else if (dfsLast[exitNode]->inEdges.size() < dfsLast[j]->inEdges.size())
|
||||||
pProc->dfsLast[j]->numInEdges)
|
|
||||||
exitNode = j;
|
exitNode = j;
|
||||||
}
|
}
|
||||||
pProc->dfsLast[i]->caseTail = exitNode;
|
dfsLast[i]->caseTail = exitNode;
|
||||||
|
|
||||||
/* Tag nodes that belong to the case by recording the
|
/* Tag nodes that belong to the case by recording the
|
||||||
* header field with caseHeader. */
|
* header field with caseHeader. */
|
||||||
insertList (caseNodes, i);
|
insertList (caseNodes, i);
|
||||||
pProc->dfsLast[i]->caseHead = i;
|
dfsLast[i]->caseHead = i;
|
||||||
for (j = 0; j < caseHeader->numOutEdges; j++)
|
for (j = 0; j < caseHeader->numOutEdges; j++)
|
||||||
tagNodesInCase (caseHeader->edges[j].BBptr, caseNodes, i,
|
tagNodesInCase (caseHeader->edges[j].BBptr, caseNodes, i, exitNode);
|
||||||
exitNode);
|
|
||||||
if (exitNode != NO_NODE)
|
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 */
|
/* 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 */
|
desc, /* Index for descendant */
|
||||||
followInEdges, /* Largest # in-edges so far */
|
followInEdges, /* Largest # in-edges so far */
|
||||||
follow; /* Possible follow node */
|
follow; /* Possible follow node */
|
||||||
nodeList domDesc, /* List of nodes dominated by curr */
|
nodeList domDesc, /* List of nodes dominated by curr */
|
||||||
unresolved, /* List of unresolved if nodes */
|
unresolved /* List of unresolved if nodes */
|
||||||
*l; /* Temporary list */
|
;
|
||||||
BB * currNode, /* Pointer to current node */
|
BB * currNode, /* Pointer to current node */
|
||||||
* pbb;
|
* pbb;
|
||||||
|
|
||||||
/* Linear scan of nodes in reverse dfsLast order */
|
/* 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 */
|
if (currNode->flg & INVALID_BB) /* Do not process invalid BBs */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((currNode->nodeType == TWO_BRANCH) &&
|
if ((currNode->nodeType == TWO_BRANCH) && (!currNode->back().isLlFlag(JX_LOOP)))
|
||||||
(! (pProc->Icode.GetLlFlag(currNode->start + currNode->length - 1)
|
|
||||||
& JX_LOOP)))
|
|
||||||
{
|
{
|
||||||
followInEdges = 0;
|
followInEdges = 0;
|
||||||
follow = 0;
|
follow = 0;
|
||||||
|
|
||||||
/* Find all nodes that have this node as immediate dominator */
|
/* 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);
|
insertList (domDesc, desc);
|
||||||
pbb = pProc->dfsLast[desc];
|
pbb = dfsLast[desc];
|
||||||
if ((pbb->numInEdges - pbb->numBackEdges) >= followInEdges)
|
if ((pbb->inEdges.size() - pbb->numBackEdges) >= followInEdges)
|
||||||
{
|
{
|
||||||
follow = desc;
|
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;
|
currNode->ifFollow = follow;
|
||||||
if (!unresolved.empty())
|
if (!unresolved.empty())
|
||||||
flagNodes (unresolved, follow, pProc);
|
flagNodes (unresolved, follow, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
insertList (unresolved, curr);
|
insertList (unresolved, curr);
|
||||||
@ -515,178 +510,170 @@ void Function::compoundCond()
|
|||||||
if (pbb->flg & INVALID_BB)
|
if (pbb->flg & INVALID_BB)
|
||||||
continue;
|
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;
|
obb = t->edges[THEN].BBptr;
|
||||||
e = pbb->edges[ELSE].BBptr;
|
|
||||||
|
|
||||||
/* Check (X || Y) case */
|
/* Construct compound DBL_OR expression */
|
||||||
if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) &&
|
picode = &pbb->back();
|
||||||
(t->numInEdges == 1) && (t->edges[ELSE].BBptr == e))
|
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;
|
auto iter=find(obb->inEdges.begin(),obb->inEdges.end(),t);
|
||||||
|
if(iter!=obb->inEdges.end())
|
||||||
/* Construct compound DBL_OR expression */
|
*iter = pbb;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check (!X && Y) case */
|
/* New THEN out-edge of pbb */
|
||||||
else if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) &&
|
pbb->edges[THEN].BBptr = obb;
|
||||||
(t->numInEdges == 1) && (t->edges[THEN].BBptr == e))
|
|
||||||
{
|
|
||||||
obb = t->edges[ELSE].BBptr;
|
|
||||||
|
|
||||||
/* Construct compound DBL_AND expression */
|
/* Remove in-edge t to e */
|
||||||
picode = this->Icode.GetIcode(pbb->start + pbb->length -1);
|
auto iter=std::find(e->inEdges.begin(),e->inEdges.end(),t);
|
||||||
ticode = this->Icode.GetIcode(t->start + t->length -1);
|
assert(iter!=e->inEdges.end());
|
||||||
inverseCondOp (&picode->ic.hl.oper.exp);
|
e->inEdges.erase(iter);
|
||||||
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
t->flg |= INVALID_BB;
|
||||||
ticode->ic.hl.oper.exp, DBL_AND);
|
|
||||||
picode->ic.hl.oper.exp = exp;
|
|
||||||
|
|
||||||
/* Replace in-edge to obb from t to pbb */
|
if (pbb->flg & IS_LATCH_NODE)
|
||||||
auto iter=std::find(obb->inEdges.begin(),obb->inEdges.end(),t);
|
this->dfsLast[t->dfsLastNum] = pbb;
|
||||||
assert(iter!=obb->inEdges.end());
|
else
|
||||||
*iter=pbb;
|
i--; /* to repeat this analysis */
|
||||||
|
|
||||||
/* New THEN and ELSE out-edges of pbb */
|
change = TRUE;
|
||||||
pbb->edges[THEN].BBptr = e;
|
}
|
||||||
pbb->edges[ELSE].BBptr = obb;
|
|
||||||
|
|
||||||
/* Remove in-edge t to e */
|
/* Check (!X && Y) case */
|
||||||
iter=std::find(e->inEdges.begin(),e->inEdges.end(),t);
|
else if ((t->nodeType == TWO_BRANCH) && (t->numHlIcodes == 1) &&
|
||||||
assert(iter!=e->inEdges.end());
|
(t->inEdges.size() == 1) && (t->edges[THEN].BBptr == e))
|
||||||
e->inEdges.erase(iter); /* looses 1 arc */
|
{
|
||||||
e->numInEdges--; /* looses 1 arc */
|
obb = t->edges[ELSE].BBptr;
|
||||||
assert(t->inEdges.size()==t->numInEdges);
|
|
||||||
t->flg |= INVALID_BB;
|
|
||||||
|
|
||||||
if (pbb->flg & IS_LATCH_NODE)
|
/* Construct compound DBL_AND expression */
|
||||||
this->dfsLast[t->dfsLastNum] = pbb;
|
picode = &pbb->back();
|
||||||
else
|
ticode = &t->back();
|
||||||
i--; /* to repeat this analysis */
|
|
||||||
|
|
||||||
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 */
|
/* Replace in-edge to obb from t to pbb */
|
||||||
else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) &&
|
auto iter=std::find(obb->inEdges.begin(),obb->inEdges.end(),t);
|
||||||
(e->numInEdges == 1) && (e->edges[THEN].BBptr == t))
|
assert(iter!=obb->inEdges.end());
|
||||||
{
|
*iter=pbb;
|
||||||
obb = e->edges[ELSE].BBptr;
|
|
||||||
|
|
||||||
/* Construct compound DBL_AND expression */
|
/* New THEN and ELSE out-edges of pbb */
|
||||||
picode = this->Icode.GetIcode(pbb->start + pbb->length -1);
|
pbb->edges[THEN].BBptr = e;
|
||||||
ticode = this->Icode.GetIcode(t->start + t->length -1);
|
pbb->edges[ELSE].BBptr = obb;
|
||||||
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 */
|
/* Remove in-edge t to e */
|
||||||
auto iter = std::find(obb->inEdges.begin(),obb->inEdges.end(),e);
|
iter=std::find(e->inEdges.begin(),e->inEdges.end(),t);
|
||||||
assert(iter!=obb->inEdges.end());
|
assert(iter!=e->inEdges.end());
|
||||||
*iter=pbb;
|
e->inEdges.erase(iter); /* looses 1 arc */
|
||||||
/* New ELSE out-edge of pbb */
|
t->flg |= INVALID_BB;
|
||||||
pbb->edges[ELSE].BBptr = obb;
|
|
||||||
|
|
||||||
/* Remove in-edge e to t */
|
if (pbb->flg & IS_LATCH_NODE)
|
||||||
iter = std::find(t->inEdges.begin(),t->inEdges.end(),e);
|
this->dfsLast[t->dfsLastNum] = pbb;
|
||||||
assert(iter!=t->inEdges.end());
|
else
|
||||||
t->inEdges.erase(iter);
|
i--; /* to repeat this analysis */
|
||||||
t->numInEdges--; /* looses 1 arc */
|
|
||||||
assert(t->inEdges.size()==t->numInEdges);
|
|
||||||
e->flg |= INVALID_BB;
|
|
||||||
|
|
||||||
if (pbb->flg & IS_LATCH_NODE)
|
change = TRUE;
|
||||||
this->dfsLast[e->dfsLastNum] = pbb;
|
}
|
||||||
else
|
|
||||||
i--; /* to repeat this analysis */
|
|
||||||
|
|
||||||
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 */
|
/* Construct compound DBL_AND expression */
|
||||||
else if ((e->nodeType == TWO_BRANCH) && (e->numHlIcodes == 1) &&
|
picode = &pbb->back();
|
||||||
(e->numInEdges == 1) && (e->edges[ELSE].BBptr == t))
|
ticode = &t->back();
|
||||||
{
|
|
||||||
obb = e->edges[THEN].BBptr;
|
|
||||||
|
|
||||||
/* Construct compound DBL_OR expression */
|
exp = COND_EXPR::boolOp (picode->ic.hl.oper.exp,
|
||||||
picode = this->Icode.GetIcode(pbb->start + pbb->length -1);
|
ticode->ic.hl.oper.exp, DBL_AND);
|
||||||
ticode = this->Icode.GetIcode(t->start + t->length -1);
|
picode->ic.hl.oper.exp = exp;
|
||||||
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 */
|
/* 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);
|
||||||
auto iter = std::find(obb->inEdges.begin(),obb->inEdges.end(),e);
|
assert(iter!=obb->inEdges.end());
|
||||||
assert(iter!=obb->inEdges.end());
|
*iter=pbb;
|
||||||
*iter=pbb;
|
/* New ELSE out-edge of pbb */
|
||||||
|
pbb->edges[ELSE].BBptr = obb;
|
||||||
|
|
||||||
/* New THEN and ELSE out-edges of pbb */
|
/* Remove in-edge e to t */
|
||||||
pbb->edges[THEN].BBptr = obb;
|
iter = std::find(t->inEdges.begin(),t->inEdges.end(),e);
|
||||||
pbb->edges[ELSE].BBptr = t;
|
assert(iter!=t->inEdges.end());
|
||||||
|
t->inEdges.erase(iter);
|
||||||
|
e->flg |= INVALID_BB;
|
||||||
|
|
||||||
/* Remove in-edge e to t */
|
if (pbb->flg & IS_LATCH_NODE)
|
||||||
iter = std::find(t->inEdges.begin(),t->inEdges.end(),e);
|
this->dfsLast[e->dfsLastNum] = pbb;
|
||||||
assert(iter!=t->inEdges.end());
|
else
|
||||||
t->inEdges.erase(iter);
|
i--; /* to repeat this analysis */
|
||||||
t->numInEdges--; /* looses 1 arc */
|
|
||||||
assert(t->numInEdges=t->inEdges.size());
|
|
||||||
e->flg |= INVALID_BB;
|
|
||||||
|
|
||||||
if (pbb->flg & IS_LATCH_NODE)
|
change = TRUE;
|
||||||
this->dfsLast[e->dfsLastNum] = pbb;
|
}
|
||||||
else
|
|
||||||
i--; /* to repeat this analysis */
|
|
||||||
|
|
||||||
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 */
|
/* Structuring algorithm to find the structures of the graph pProc->cfg */
|
||||||
|
void Function::structure(derSeq *derivedG)
|
||||||
{
|
{
|
||||||
/* Find immediate dominators of the graph */
|
/* Find immediate dominators of the graph */
|
||||||
findImmedDom();
|
findImmedDom();
|
||||||
if (hasCase)
|
if (hasCase)
|
||||||
structCases(this);
|
structCases();
|
||||||
structLoops(this, derivedG);
|
structLoops(derivedG);
|
||||||
structIfs(this);
|
structIfs();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,8 @@ Int STKFRAME::getLocVar(Int off)
|
|||||||
|
|
||||||
/* Returns a string with the source operand of Icode */
|
/* Returns a string with the source operand of Icode */
|
||||||
static COND_EXPR *srcIdent (ICODE * Icode, Function * pProc, Int i, ICODE * duIcode, operDu du)
|
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 */
|
if (Icode->ic.ll.flg & I) /* immediate operand */
|
||||||
{
|
{
|
||||||
@ -99,7 +100,7 @@ void Function::elimCondCodes ()
|
|||||||
|
|
||||||
case iOR:
|
case iOR:
|
||||||
lhs = Icode.GetIcode(defAt-1)->ic.hl.oper.asgn.lhs->clone();
|
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)
|
if (Icode.GetLlFlag(defAt-1) & B)
|
||||||
rhs = COND_EXPR::idKte (0, 1);
|
rhs = COND_EXPR::idKte (0, 1);
|
||||||
else
|
else
|
||||||
@ -164,8 +165,8 @@ void Function::elimCondCodes ()
|
|||||||
{
|
{
|
||||||
exp = prev->ic.hl.oper.exp->clone();
|
exp = prev->ic.hl.oper.exp->clone();
|
||||||
exp->changeBoolOp (condOpJCond[Icode.GetLlOpcode(useAt-1)-iJB]);
|
exp->changeBoolOp (condOpJCond[Icode.GetLlOpcode(useAt-1)-iJB]);
|
||||||
copyDU (Icode.GetIcode(useAt-1), prev, eUSE, eUSE);
|
Icode[useAt-1].copyDU(*prev, eUSE, eUSE);
|
||||||
Icode.GetIcode(useAt-1)->setJCond(exp);
|
Icode[useAt-1].setJCond(exp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Error - definition not found for use of a cond code */
|
/* Error - definition not found for use of a cond code */
|
||||||
@ -452,8 +453,7 @@ void Function::genDU1 ()
|
|||||||
{
|
{
|
||||||
if (! (pbb->liveOut & duReg[regi])) /* not liveOut */
|
if (! (pbb->liveOut & duReg[regi])) /* not liveOut */
|
||||||
{
|
{
|
||||||
res = removeDefRegi (regi, picode, defRegIdx+1,
|
res = picode->removeDefRegi (regi, defRegIdx+1,&localId);
|
||||||
&localId);
|
|
||||||
|
|
||||||
/* Backpatch any uses of this instruction, within
|
/* Backpatch any uses of this instruction, within
|
||||||
* the same BB, if the instruction was invalidated */
|
* the same BB, if the instruction was invalidated */
|
||||||
@ -567,7 +567,7 @@ static boolT xClear (COND_EXPR *rhs, Int f, Int t, Int lastBBinst, Function * pp
|
|||||||
ICODE * picode;
|
ICODE * picode;
|
||||||
|
|
||||||
if (rhs == NULL)
|
if (rhs == NULL)
|
||||||
return (FALSE);
|
return false;
|
||||||
|
|
||||||
switch (rhs->type) {
|
switch (rhs->type) {
|
||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
@ -580,15 +580,15 @@ static boolT xClear (COND_EXPR *rhs, Int f, Int t, Int lastBBinst, Function * pp
|
|||||||
(picode[i].invalid == FALSE))
|
(picode[i].invalid == FALSE))
|
||||||
{
|
{
|
||||||
if (picode[i].du.def & duReg[regi])
|
if (picode[i].du.def & duReg[regi])
|
||||||
return (FALSE);
|
return false;
|
||||||
}
|
}
|
||||||
if (i < lastBBinst)
|
if (i < lastBBinst)
|
||||||
return (TRUE);
|
return true;
|
||||||
else
|
else
|
||||||
return (FALSE);
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return (TRUE);
|
return true;
|
||||||
/* else if (rhs->expr.ident.idType == LONG_VAR)
|
/* else if (rhs->expr.ident.idType == LONG_VAR)
|
||||||
{
|
{
|
||||||
missing all other identifiers ****
|
missing all other identifiers ****
|
||||||
@ -597,7 +597,7 @@ missing all other identifiers ****
|
|||||||
case BOOLEAN_OP:
|
case BOOLEAN_OP:
|
||||||
res = xClear (rhs->expr.boolExpr.rhs, f, t, lastBBinst, pproc);
|
res = xClear (rhs->expr.boolExpr.rhs, f, t, lastBBinst, pproc);
|
||||||
if (res == FALSE)
|
if (res == FALSE)
|
||||||
return (FALSE);
|
return false;
|
||||||
return (xClear (rhs->expr.boolExpr.lhs, f, t, lastBBinst, pproc));
|
return (xClear (rhs->expr.boolExpr.lhs, f, t, lastBBinst, pproc));
|
||||||
|
|
||||||
case NEGATION:
|
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. */
|
* For HLI_CALL hlIcodes, places the arguments in the argument list. */
|
||||||
void Function::findExps()
|
void Function::findExps()
|
||||||
{
|
{
|
||||||
Int i, j, k, lastInst, lastInstN, numHlIcodes;
|
Int i, j, k, lastInst, numHlIcodes;
|
||||||
ICODE * picode, /* Current icode */
|
ICODE * picode, /* Current icode */
|
||||||
* ticode; /* Target icode */
|
* ticode; /* Target icode */
|
||||||
BB * pbb; /* Current and next basic block */
|
BB * pbb; /* Current and next basic block */
|
||||||
@ -728,7 +728,7 @@ void Function::findExps()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_CALL: /* register arguments */
|
case HLI_CALL: /* register arguments */
|
||||||
newRegArg (this, picode, ticode);
|
newRegArg (picode, ticode);
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
@ -866,7 +866,7 @@ void Function::findExps()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_CALL: /* register arguments */
|
case HLI_CALL: /* register arguments */
|
||||||
newRegArg (this, picode, ticode);
|
newRegArg ( picode, ticode);
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -23,7 +23,7 @@ PROG prog; /* programs fields */
|
|||||||
OPTION option; /* Command line options */
|
OPTION option; /* Command line options */
|
||||||
//Function * pProcList; /* List of procedures, topologically sort */
|
//Function * pProcList; /* List of procedures, topologically sort */
|
||||||
//Function * pLastProc; /* Pointer to last node in procedure list */
|
//Function * pLastProc; /* Pointer to last node in procedure list */
|
||||||
std::list<Function> pProcList;
|
FunctionListType pProcList;
|
||||||
CALL_GRAPH *callGraph; /* Call graph of the program */
|
CALL_GRAPH *callGraph; /* Call graph of the program */
|
||||||
|
|
||||||
static char *initargs(int argc, char *argv[]);
|
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);
|
imageOff = off + ((dword)pProc->state.r[rCS] << 4);
|
||||||
/* Search procedure list for one with appropriate entry point */
|
/* 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; });
|
[imageOff](const Function &f) -> bool { return f.procEntry==imageOff; });
|
||||||
if(iter==pProcList.end())
|
if(iter==pProcList.end())
|
||||||
{
|
{
|
||||||
/* No existing proc entry */
|
/* No existing proc entry */
|
||||||
//ERROR: dereferencing NULL !?!
|
//ERROR: dereferencing NULL !?!
|
||||||
//LibCheck(*iter);
|
//LibCheck(*iter);
|
||||||
Function x;
|
Function *x=Function::Create();
|
||||||
x.procEntry=imageOff;
|
x->procEntry=imageOff;
|
||||||
LibCheck(x);
|
LibCheck(*x);
|
||||||
if (x.flg & PROC_ISLIB)
|
if (x->flg & PROC_ISLIB)
|
||||||
{
|
{
|
||||||
/* No entry for this proc, but it is a library function.
|
/* No entry for this proc, but it is a library function.
|
||||||
Create an entry for it */
|
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()
|
void Function::createCFG()
|
||||||
{
|
{
|
||||||
/* Splits Icode associated with the procedure into Basic Blocks.
|
/* Splits Icode associated with the procedure into Basic Blocks.
|
||||||
* The links between BBs represent the control flow graph of the
|
* The links between BBs represent the control flow graph of the
|
||||||
* procedure.
|
* procedure.
|
||||||
* A Basic Block is defined to end on one of the following instructions:
|
* A Basic Block is defined to end on one of the following instructions:
|
||||||
* 1) Conditional and unconditional jumps
|
* 1) Conditional and unconditional jumps
|
||||||
* 2) CALL(F)
|
* 2) CALL(F)
|
||||||
* 3) RET(F)
|
* 3) RET(F)
|
||||||
* 4) On the instruction before a join (a flagged TARGET)
|
* 4) On the instruction before a join (a flagged TARGET)
|
||||||
* 5) Repeated string instructions
|
* 5) Repeated string instructions
|
||||||
* 6) End of procedure
|
* 6) End of procedure
|
||||||
*/
|
*/
|
||||||
Int i;
|
Int i;
|
||||||
Int ip, start;
|
Int ip, start;
|
||||||
BB * psBB;
|
BB * psBB;
|
||||||
BB * pBB;
|
BB * pBB;
|
||||||
ICODE * pIcode = Icode.GetFirstIcode();
|
ICODE * pIcode = Icode.GetFirstIcode();
|
||||||
|
|
||||||
stats.numBBbef = stats.numBBaft = 0;
|
stats.numBBbef = stats.numBBaft = 0;
|
||||||
@ -47,7 +47,9 @@ void Function::createCFG()
|
|||||||
! (pIcode->ic.ll.flg & TERMINATES) &&
|
! (pIcode->ic.ll.flg & TERMINATES) &&
|
||||||
pIcode->ic.ll.opcode != iJMP && pIcode->ic.ll.opcode != iJMPF &&
|
pIcode->ic.ll.opcode != iJMP && pIcode->ic.ll.opcode != iJMPF &&
|
||||||
pIcode->ic.ll.opcode != iRET && pIcode->ic.ll.opcode != iRETF)
|
pIcode->ic.ll.opcode != iRET && pIcode->ic.ll.opcode != iRETF)
|
||||||
|
{
|
||||||
pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this);
|
pBB=BB::Create(start, ip, NOWHERE_NODE, 0, this);
|
||||||
|
}
|
||||||
|
|
||||||
/* Only process icodes that have valid instructions */
|
/* Only process icodes that have valid instructions */
|
||||||
else if ((pIcode->ic.ll.flg & NO_CODE) != NO_CODE)
|
else if ((pIcode->ic.ll.flg & NO_CODE) != NO_CODE)
|
||||||
@ -64,7 +66,10 @@ CondJumps:
|
|||||||
pBB->edges[0].ip = (dword)start;
|
pBB->edges[0].ip = (dword)start;
|
||||||
/* This is for jumps off into nowhere */
|
/* This is for jumps off into nowhere */
|
||||||
if (pIcode->ic.ll.flg & NO_LABEL)
|
if (pIcode->ic.ll.flg & NO_LABEL)
|
||||||
|
{
|
||||||
pBB->numOutEdges--;
|
pBB->numOutEdges--;
|
||||||
|
pBB->edges.pop_back();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
pBB->edges[1].ip = pIcode->ic.ll.immed.op;
|
pBB->edges[1].ip = pIcode->ic.ll.immed.op;
|
||||||
break;
|
break;
|
||||||
@ -76,13 +81,13 @@ CondJumps:
|
|||||||
case iJMPF: case iJMP:
|
case iJMPF: case iJMP:
|
||||||
if (pIcode->ic.ll.flg & SWITCH)
|
if (pIcode->ic.ll.flg & SWITCH)
|
||||||
{
|
{
|
||||||
pBB = BB::Create(start, ip, MULTI_BRANCH,
|
pBB = BB::Create(start, ip, MULTI_BRANCH, pIcode->ic.ll.caseTbl.numEntries, this);
|
||||||
pIcode->ic.ll.caseTbl.numEntries, this);
|
|
||||||
for (i = 0; i < pIcode->ic.ll.caseTbl.numEntries; i++)
|
for (i = 0; i < pIcode->ic.ll.caseTbl.numEntries; i++)
|
||||||
pBB->edges[i].ip = pIcode->ic.ll.caseTbl.entries[i];
|
pBB->edges[i].ip = pIcode->ic.ll.caseTbl.entries[i];
|
||||||
hasCase = TRUE;
|
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 = BB::Create(start, ip, ONE_BRANCH, 1, this);
|
||||||
pBB->edges[0].ip = pIcode->ic.ll.immed.op;
|
pBB->edges[0].ip = pIcode->ic.ll.immed.op;
|
||||||
}
|
}
|
||||||
@ -137,17 +142,17 @@ CondJumps:
|
|||||||
{
|
{
|
||||||
ip = pBB->edges[i].ip;
|
ip = pBB->edges[i].ip;
|
||||||
if (ip >= SYNTHESIZED_MIN)
|
if (ip >= SYNTHESIZED_MIN)
|
||||||
fatalError (INVALID_SYNTHETIC_BB);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(),
|
fatalError (INVALID_SYNTHETIC_BB);
|
||||||
[ip](BB *psBB)->bool {return psBB->start==ip;});
|
return ;
|
||||||
|
}
|
||||||
|
auto iter2=std::find_if(heldBBs.begin(),heldBBs.end(),
|
||||||
|
[ip](BB *psBB)->bool {return psBB->begin()==ip;});
|
||||||
if(iter2==heldBBs.end())
|
if(iter2==heldBBs.end())
|
||||||
fatalError(NO_BB, ip, name);
|
fatalError(NO_BB, ip, name);
|
||||||
psBB = *iter2;
|
psBB = *iter2;
|
||||||
pBB->edges[i].BBptr = psBB;
|
pBB->edges[i].BBptr = psBB;
|
||||||
psBB->numInEdges++;
|
psBB->inEdges.push_back(0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,19 +208,19 @@ void Function::compressCFG()
|
|||||||
for (;iter!=cfg.end(); ++iter)
|
for (;iter!=cfg.end(); ++iter)
|
||||||
{
|
{
|
||||||
pBB = *iter;
|
pBB = *iter;
|
||||||
pBB->inEdges.resize(pBB->numInEdges,0);
|
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
|
||||||
if (pBB->numInEdges != 0 && (pBB->nodeType == ONE_BRANCH || pBB->nodeType == TWO_BRANCH))
|
continue;
|
||||||
for (i = 0; i < pBB->numOutEdges; i++)
|
for (i = 0; i < pBB->numOutEdges; i++)
|
||||||
{
|
{
|
||||||
ip = pBB->start + pBB->length - 1;
|
ip = pBB->rbegin();
|
||||||
pNxt = rmJMP(this, ip, pBB->edges[i].BBptr);
|
pNxt = rmJMP(this, ip, pBB->edges[i].BBptr);
|
||||||
|
|
||||||
if (pBB->numOutEdges) /* Might have been clobbered */
|
if (pBB->numOutEdges) /* Might have been clobbered */
|
||||||
{
|
{
|
||||||
pBB->edges[i].BBptr = pNxt;
|
pBB->edges[i].BBptr = pNxt;
|
||||||
Icode.SetImmediateOp(ip, (dword)pNxt->start);
|
Icode.SetImmediateOp(ip, (dword)pNxt->start);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next is a depth-first traversal merging any FALL_NODE or
|
/* 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)
|
for(auto iter=cfg.begin(); iter!=cfg.end(); ++iter)
|
||||||
{
|
{
|
||||||
pBB = *iter;
|
pBB = *iter;
|
||||||
if (pBB->numInEdges == 0)
|
if (pBB->inEdges.empty())
|
||||||
{
|
{
|
||||||
if (iter == cfg.begin()) /* Init it misses out on */
|
if (iter == cfg.begin()) /* Init it misses out on */
|
||||||
pBB->index = UN_INIT;
|
pBB->index = UN_INIT;
|
||||||
@ -244,7 +249,7 @@ void Function::compressCFG()
|
|||||||
}
|
}
|
||||||
else
|
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;
|
marker += DFS_JMP;
|
||||||
|
|
||||||
while (pBB->nodeType == ONE_BRANCH && pBB->length == 1) {
|
while (pBB->nodeType == ONE_BRANCH && pBB->length == 1)
|
||||||
if (pBB->traversed != marker) {
|
{
|
||||||
|
if (pBB->traversed != marker)
|
||||||
|
{
|
||||||
pBB->traversed = marker;
|
pBB->traversed = marker;
|
||||||
if (--pBB->numInEdges)
|
pBB->inEdges.pop_back();
|
||||||
pBB->edges[0].BBptr->numInEdges++;
|
if (not pBB->inEdges.empty())
|
||||||
|
{
|
||||||
|
pBB->edges[0].BBptr->inEdges.push_back(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pProc->Icode.SetLlFlag(pBB->start, NO_CODE);
|
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);
|
pProc->Icode.SetImmediateOp(pBB->start, (dword)pBB->start);
|
||||||
do {
|
do {
|
||||||
pBB = pBB->edges[0].BBptr;
|
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.SetLlFlag(pBB->start, NO_CODE);
|
||||||
pProc->Icode.SetLlInvalid(pBB->start, TRUE);
|
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 there's no other edges into child can merge */
|
||||||
if (pChild->numInEdges != 1)
|
if (pChild->inEdges.size() != 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
nodeType = pChild->nodeType;
|
nodeType = pChild->nodeType;
|
||||||
@ -337,7 +348,8 @@ void BB::mergeFallThrough( CIcodeRec &Icode)
|
|||||||
numOutEdges = pChild->numOutEdges;
|
numOutEdges = pChild->numOutEdges;
|
||||||
edges.swap(pChild->edges);
|
edges.swap(pChild->edges);
|
||||||
|
|
||||||
pChild->numOutEdges = pChild->numInEdges = 0;
|
pChild->numOutEdges = 0;
|
||||||
|
pChild->inEdges.clear();
|
||||||
pChild->edges.clear();
|
pChild->edges.clear();
|
||||||
}
|
}
|
||||||
traversed = DFS_MERGE;
|
traversed = DFS_MERGE;
|
||||||
@ -368,7 +380,7 @@ void BB::dfsNumbering(std::vector<BB *> &dfsLast, Int *first, Int *last)
|
|||||||
pChild->inEdges[pChild->index++] = this;
|
pChild->inEdges[pChild->index++] = this;
|
||||||
|
|
||||||
/* Is this the last visit? */
|
/* Is this the last visit? */
|
||||||
if (pChild->index == pChild->numInEdges)
|
if (pChild->index == pChild->inEdges.size())
|
||||||
pChild->index = UN_INIT;
|
pChild->index = UN_INIT;
|
||||||
|
|
||||||
if (pChild->traversed != DFS_NUM)
|
if (pChild->traversed != DFS_NUM)
|
||||||
|
|||||||
@ -83,37 +83,39 @@ void ICODE ::invalidate()
|
|||||||
/* Removes the defined register regi from the lhs subtree. If all registers
|
/* Removes the defined register regi from the lhs subtree. If all registers
|
||||||
* of this instruction are unused, the instruction is invalidated (ie.
|
* of this instruction are unused, the instruction is invalidated (ie.
|
||||||
* removed) */
|
* removed) */
|
||||||
boolT removeDefRegi (byte regi, ICODE *picode, Int thisDefIdx, LOCAL_ID *locId)
|
boolT ICODE::removeDefRegi (byte regi, Int thisDefIdx, LOCAL_ID *locId)
|
||||||
{ Int numDefs;
|
{
|
||||||
|
Int numDefs;
|
||||||
|
|
||||||
numDefs = picode->du1.numRegsDef;
|
numDefs = du1.numRegsDef;
|
||||||
if (numDefs == thisDefIdx)
|
if (numDefs == thisDefIdx)
|
||||||
for ( ; numDefs > 0; numDefs--)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numDefs == 0)
|
if (numDefs == 0)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
invalidate();
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (picode->ic.hl.opcode) {
|
switch (ic.hl.opcode) {
|
||||||
case HLI_ASSIGN: removeRegFromLong (regi, locId,
|
case HLI_ASSIGN:
|
||||||
picode->ic.hl.oper.asgn.lhs);
|
removeRegFromLong (regi, locId,ic.hl.oper.asgn.lhs);
|
||||||
picode->du1.numRegsDef--;
|
du1.numRegsDef--;
|
||||||
picode->du.def &= maskDuReg[regi];
|
du.def &= maskDuReg[regi];
|
||||||
break;
|
break;
|
||||||
case HLI_POP:
|
case HLI_POP:
|
||||||
case HLI_PUSH: removeRegFromLong (regi, locId, picode->ic.hl.oper.exp);
|
case HLI_PUSH:
|
||||||
picode->du1.numRegsDef--;
|
removeRegFromLong (regi, locId, ic.hl.oper.exp);
|
||||||
picode->du.def &= maskDuReg[regi];
|
du1.numRegsDef--;
|
||||||
|
du.def &= maskDuReg[regi];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (FALSE);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
|
#include "dcc.h"
|
||||||
#include "types.h" // Common types like byte, etc
|
#include "types.h" // Common types like byte, etc
|
||||||
#include "ast.h" // Some icode types depend on these
|
#include "ast.h" // Some icode types depend on these
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
@ -118,6 +119,27 @@ ICODE * CIcodeRec::GetIcode(int ip)
|
|||||||
return &at(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 < pEnd)
|
||||||
if ((pIcode+1)->ic.ll.opcode == iADC)
|
if ((pIcode+1)->ic.ll.opcode == iADC)
|
||||||
return (TRUE);
|
return true;
|
||||||
return (FALSE);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -343,8 +343,8 @@ static boolT idiom6 (ICODE * pIcode, ICODE * pEnd)
|
|||||||
{
|
{
|
||||||
if (pIcode < pEnd)
|
if (pIcode < pEnd)
|
||||||
if ((pIcode+1)->ic.ll.opcode == iSBB)
|
if ((pIcode+1)->ic.ll.opcode == iSBB)
|
||||||
return (TRUE);
|
return true;
|
||||||
return (FALSE);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -364,21 +364,21 @@ static boolT idiom7 (ICODE * pIcode)
|
|||||||
if (dst->regi == 0) /* global variable */
|
if (dst->regi == 0) /* global variable */
|
||||||
{
|
{
|
||||||
if ((dst->segValue == src->segValue) && (dst->off == src->off))
|
if ((dst->segValue == src->segValue) && (dst->off == src->off))
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
else if (dst->regi < INDEXBASE) /* register */
|
else if (dst->regi < INDEXBASE) /* register */
|
||||||
{
|
{
|
||||||
if (dst->regi == src->regi)
|
if (dst->regi == src->regi)
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
else if ((dst->off) && (dst->seg == rSS) && (dst->regi == INDEXBASE + 6))
|
else if ((dst->off) && (dst->seg == rSS) && (dst->regi == INDEXBASE + 6))
|
||||||
/* offset from BP */
|
/* offset from BP */
|
||||||
{
|
{
|
||||||
if ((dst->off == src->off) && (dst->seg == src->seg) &&
|
if ((dst->off == src->off) && (dst->seg == src->seg) &&
|
||||||
(dst->regi == src->regi))
|
(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))
|
(dst->regi < INDEXBASE))
|
||||||
{
|
{
|
||||||
if ((dst->regi == rDX) && ((picode+1)->ic.ll.dst.regi == rAX))
|
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))
|
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) &&
|
if (((pIcode+1)->ic.ll.opcode == iRCR) &&
|
||||||
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
||||||
((pIcode+1)->ic.ll.immed.op == 1))
|
((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) &&
|
if (((pIcode+1)->ic.ll.opcode == iRCL) &&
|
||||||
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
||||||
((pIcode+1)->ic.ll.immed.op == 1))
|
((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) &&
|
if (((pIcode+1)->ic.ll.opcode == iRCR) &&
|
||||||
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
(((pIcode+1)->ic.ll.flg & I) == I) &&
|
||||||
((pIcode+1)->ic.ll.immed.op == 1))
|
((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) &&
|
if (((pIcode+1)->ic.ll.opcode == iJNE) &&
|
||||||
((pIcode+2)->ic.ll.opcode != iCMP) &&
|
((pIcode+2)->ic.ll.opcode != iCMP) &&
|
||||||
((pIcode+3)->ic.ll.opcode != iJE))
|
((pIcode+3)->ic.ll.opcode != iJE))
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
else /* at the end of the procedure */
|
else /* at the end of the procedure */
|
||||||
if (((pIcode+1) < pEnd) && ((pIcode+1)->ic.ll.opcode == iJNE))
|
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 (*regH == (picode+1)->ic.ll.src.regi)
|
||||||
{
|
{
|
||||||
if ((*regL == rAX) && (*regH == rDX))
|
if ((*regL == rAX) && (*regH == rDX))
|
||||||
return (TRUE);
|
return true;
|
||||||
if ((*regL == rBX) && (*regH == rCX))
|
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->ic.ll.dst.segValue) &&
|
||||||
((pIcode+2)->ic.ll.dst.off ==
|
((pIcode+2)->ic.ll.dst.off ==
|
||||||
pIcode->ic.ll.dst.off))
|
pIcode->ic.ll.dst.off))
|
||||||
return (TRUE);
|
return true;
|
||||||
break;
|
break;
|
||||||
case REGISTER: if ((pIcode+2)->ic.ll.dst.regi ==
|
case REGISTER: if ((pIcode+2)->ic.ll.dst.regi ==
|
||||||
pIcode->ic.ll.dst.regi)
|
pIcode->ic.ll.dst.regi)
|
||||||
return (TRUE);
|
return true;
|
||||||
break;
|
break;
|
||||||
case PARAM:
|
case PARAM:
|
||||||
case LOCAL_VAR: if ((pIcode+2)->ic.ll.dst.off ==
|
case LOCAL_VAR: if ((pIcode+2)->ic.ll.dst.off ==
|
||||||
pIcode->ic.ll.dst.off)
|
pIcode->ic.ll.dst.off)
|
||||||
return (TRUE);
|
return true;
|
||||||
break;
|
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.src.regi)) &&
|
||||||
((picode+1)->ic.ll.dst.regi == regi) &&
|
((picode+1)->ic.ll.dst.regi == regi) &&
|
||||||
((picode+2)->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+1)->ic.ll.dst.regi == regi) &&
|
||||||
(((picode+2)->ic.ll.opcode >= iJB) &&
|
(((picode+2)->ic.ll.opcode >= iJB) &&
|
||||||
((picode+2)->ic.ll.opcode < iJCXZ)))
|
((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+1)->ic.ll.dst.regi == regi) &&
|
||||||
(((picode+2)->ic.ll.opcode >= iJB) &&
|
(((picode+2)->ic.ll.opcode >= iJB) &&
|
||||||
((picode+2)->ic.ll.opcode < iJCXZ)))
|
((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)))
|
((picode->ic.ll.dst.regi == rDI) && (pproc->flg & DI_REGVAR)))
|
||||||
if ((picode < pend) && ((picode+1)->ic.ll.opcode >= iJB) &&
|
if ((picode < pend) && ((picode+1)->ic.ll.opcode >= iJB) &&
|
||||||
((picode+1)->ic.ll.opcode < iJCXZ))
|
((picode+1)->ic.ll.opcode < iJCXZ))
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
else if (picode->ic.ll.dst.off) /* stack variable */
|
else if (picode->ic.ll.dst.off) /* stack variable */
|
||||||
{
|
{
|
||||||
if ((picode < pend) && ((picode+1)->ic.ll.opcode >= iJB) &&
|
if ((picode < pend) && ((picode+1)->ic.ll.opcode >= iJB) &&
|
||||||
((picode+1)->ic.ll.opcode < iJCXZ))
|
((picode+1)->ic.ll.opcode < iJCXZ))
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
else /* indexed */
|
else /* indexed */
|
||||||
/* not supported yet */ ;
|
/* 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+2)->ic.ll.dst.regi == regi) &&
|
||||||
(((picode+3)->ic.ll.opcode >= iJB) &&
|
(((picode+3)->ic.ll.opcode >= iJB) &&
|
||||||
((picode+3)->ic.ll.opcode < iJCXZ)))
|
((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+2)->ic.ll.dst.regi == regi) &&
|
||||||
(((picode+3)->ic.ll.opcode >= iJB) &&
|
(((picode+3)->ic.ll.opcode >= iJB) &&
|
||||||
((picode+3)->ic.ll.opcode < iJCXZ)))
|
((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 */
|
Int idx; /* Index into local identifier table */
|
||||||
byte regH, regL; /* High and low registers for long word reg */
|
byte regH, regL; /* High and low registers for long word reg */
|
||||||
|
|
||||||
pIcode = Icode.GetFirstIcode();
|
pIcode = &Icode.front();
|
||||||
pEnd = pIcode + Icode.GetNumIcodes();
|
pEnd = pIcode + Icode.GetNumIcodes();
|
||||||
ip = 0;
|
ip = 0;
|
||||||
|
|
||||||
@ -1192,10 +1192,8 @@ void Function::findIdioms()
|
|||||||
case iSUB: /* Idiom 6 */
|
case iSUB: /* Idiom 6 */
|
||||||
if (idiom6 (pIcode, pEnd))
|
if (idiom6 (pIcode, pEnd))
|
||||||
{
|
{
|
||||||
lhs = COND_EXPR::idLong (&localId, DST, pIcode, LOW_FIRST,
|
lhs = COND_EXPR::idLong (&localId, DST, pIcode, LOW_FIRST, ip, USE_DEF, 1);
|
||||||
ip, USE_DEF, 1);
|
rhs = COND_EXPR::idLong (&localId, SRC, pIcode, LOW_FIRST, ip, eUSE, 1);
|
||||||
rhs = COND_EXPR::idLong (&localId, SRC, pIcode, LOW_FIRST,
|
|
||||||
ip, eUSE, 1);
|
|
||||||
exp = COND_EXPR::boolOp (lhs, rhs, SUB);
|
exp = COND_EXPR::boolOp (lhs, rhs, SUB);
|
||||||
pIcode->setAsgn(lhs, exp);
|
pIcode->setAsgn(lhs, exp);
|
||||||
(pIcode+1)->invalidate();
|
(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)
|
if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC)
|
||||||
*rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST,
|
*rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST,
|
||||||
idx, eUSE, off);
|
idx, eUSE, off);
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
else if ((longId.offH == pmHsrc->off) && (longId.offL == pmLsrc->off))
|
||||||
{
|
{
|
||||||
*lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx,
|
*lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx,
|
||||||
eDEF, off);
|
eDEF, off);
|
||||||
*rhs = COND_EXPR::idLongIdx (i);
|
*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);
|
*lhs = COND_EXPR::idLongIdx (i);
|
||||||
if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC)
|
if ((pIcode->ic.ll.flg & NO_SRC) != NO_SRC)
|
||||||
*rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, idx, eUSE, off);
|
*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))
|
else if ((longId.h == pmHsrc->regi) && (longId.l == pmLsrc->regi))
|
||||||
{
|
{
|
||||||
*lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx, eDEF, off);
|
*lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode, HIGH_FIRST, idx, eDEF, off);
|
||||||
*rhs = COND_EXPR::idLongIdx (i);
|
*rhs = COND_EXPR::idLongIdx (i);
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
return (FALSE);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,9 @@ void parse (CALL_GRAPH * *pcallGraph)
|
|||||||
state.checkStartup();
|
state.checkStartup();
|
||||||
|
|
||||||
/* Make a struct for the initial procedure */
|
/* 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)
|
if (prog.offMain != -1)
|
||||||
{
|
{
|
||||||
/* We know where main() is. Start the flow of control from there */
|
/* 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)
|
if (pIcode->ic.ll.flg & I)
|
||||||
{
|
{
|
||||||
/* Search procedure list for one with appropriate entry point */
|
/* 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) ->
|
[pIcode](const Function &f) ->
|
||||||
bool { return f.procEntry==pIcode->ic.ll.immed.op; });
|
bool { return f.procEntry==pIcode->ic.ll.immed.op; });
|
||||||
|
|
||||||
/* Create a new procedure node and save copy of the state */
|
/* Create a new procedure node and save copy of the state */
|
||||||
if (iter==pProcList.end())
|
if (iter==pProcList.end())
|
||||||
{
|
{
|
||||||
pProcList.push_back(Function());
|
pProcList.push_back(Function::Create());
|
||||||
Function &x(pProcList.back());
|
Function &x(pProcList.back());
|
||||||
iter = (++pProcList.rbegin()).base();
|
iter = (++pProcList.rbegin()).base();
|
||||||
x.procEntry = pIcode->ic.ll.immed.op;
|
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 */
|
/* A library function. No need to do any more to it */
|
||||||
pcallGraph->insertCallGraph (this, iter);
|
pcallGraph->insertCallGraph (this, iter);
|
||||||
iter = (++pProcList.rbegin()).base();
|
iter = (++pProcList.rbegin()).base();
|
||||||
|
|
||||||
Icode.GetIcode(ip)->ic.ll.immed.proc.proc = &x;
|
Icode.GetIcode(ip)->ic.ll.immed.proc.proc = &x;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,7 +49,7 @@ boolT CALL_GRAPH::insertCallGraph(ilFunction caller, ilFunction callee)
|
|||||||
if (proc == caller)
|
if (proc == caller)
|
||||||
{
|
{
|
||||||
insertArc (callee);
|
insertArc (callee);
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@ void CALL_GRAPH::write()
|
|||||||
/* Updates the argument table by including the register(s) (ie. lhs of
|
/* Updates the argument table by including the register(s) (ie. lhs of
|
||||||
* picode) and the actual expression (ie. rhs of picode).
|
* picode) and the actual expression (ie. rhs of picode).
|
||||||
* Note: register(s) are only included once in the table. */
|
* Note: register(s) are only included once in the table. */
|
||||||
void newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
void Function::newRegArg(ICODE *picode, ICODE *ticode)
|
||||||
{
|
{
|
||||||
COND_EXPR *lhs;
|
COND_EXPR *lhs;
|
||||||
STKFRAME * ps, *ts;
|
STKFRAME * ps, *ts;
|
||||||
@ -118,7 +118,7 @@ void newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
|||||||
type = lhs->expr.ident.idType;
|
type = lhs->expr.ident.idType;
|
||||||
if (type == REGISTER)
|
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)
|
if (regL < rAL)
|
||||||
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
tidx = tproc->localId.newByteWordReg(TYPE_WORD_SIGN, regL);
|
||||||
else
|
else
|
||||||
@ -126,8 +126,8 @@ void newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
|||||||
}
|
}
|
||||||
else if (type == LONG_VAR)
|
else if (type == LONG_VAR)
|
||||||
{
|
{
|
||||||
regL = pproc->localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l;
|
regL = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.l;
|
||||||
regH = pproc->localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h;
|
regH = localId.id_arr[lhs->expr.ident.idNode.longIdx].id.longId.h;
|
||||||
tidx = tproc->localId.newLongReg(TYPE_LONG_SIGN, regH, regL, 0);
|
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 */
|
/* Mask off high and low register(s) in picode */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case REGISTER:
|
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];
|
picode->du.def &= maskDuReg[id->id.regi];
|
||||||
if (id->id.regi < rAL)
|
if (id->id.regi < rAL)
|
||||||
newsym.type = TYPE_WORD_SIGN;
|
newsym.type = TYPE_WORD_SIGN;
|
||||||
@ -202,7 +202,7 @@ void newRegArg (Function * pproc, ICODE *picode, ICODE *ticode)
|
|||||||
newsym.type = TYPE_BYTE_SIGN;
|
newsym.type = TYPE_BYTE_SIGN;
|
||||||
break;
|
break;
|
||||||
case LONG_VAR:
|
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.h];
|
||||||
picode->du.def &= maskDuReg[id->id.longId.l];
|
picode->du.def &= maskDuReg[id->id.longId.l];
|
||||||
newsym.type = TYPE_LONG_SIGN;
|
newsym.type = TYPE_LONG_SIGN;
|
||||||
@ -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
|
/* Inserts the new expression (ie. the actual parameter) on the argument
|
||||||
* list.
|
* list.
|
||||||
* Returns: TRUE if it was a near call that made use of a segment register.
|
* Returns: TRUE if it was a near call that made use of a segment register.
|
||||||
* FALSE elsewhere */
|
* FALSE elsewhere */
|
||||||
{ STKFRAME * ps;
|
boolT newStkArg (ICODE *picode, COND_EXPR *exp, llIcode opcode, Function * pproc)
|
||||||
|
{
|
||||||
|
STKFRAME * ps;
|
||||||
byte regi;
|
byte regi;
|
||||||
|
|
||||||
/* Check for far procedure call, in which case, references to segment
|
/* 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;
|
regi = pproc->localId.id_arr[exp->expr.ident.idNode.regiIdx].id.regi;
|
||||||
if ((regi >= rES) && (regi <= rDS))
|
if ((regi >= rES) && (regi <= rDS))
|
||||||
if (opcode == iCALLF)
|
if (opcode == iCALLF)
|
||||||
return (FALSE);
|
return false;
|
||||||
else
|
else
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,8 @@ static boolT isJCond (llIcode opcode)
|
|||||||
* high-level conditional jump icodes (iJB..iJG) */
|
* high-level conditional jump icodes (iJB..iJG) */
|
||||||
{
|
{
|
||||||
if ((opcode >= iJB) && (opcode <= iJG))
|
if ((opcode >= iJB) && (opcode <= iJG))
|
||||||
return (TRUE);
|
return true;
|
||||||
return (FALSE);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -26,12 +26,12 @@ static boolT isLong23 (Int i, BB * pbb, ICODE * icode, Int *off, Int *arc)
|
|||||||
{ BB * t, * e, * obb2;
|
{ BB * t, * e, * obb2;
|
||||||
|
|
||||||
if (pbb->nodeType != TWO_BRANCH)
|
if (pbb->nodeType != TWO_BRANCH)
|
||||||
return (FALSE);
|
return false;
|
||||||
t = pbb->edges[THEN].BBptr;
|
t = pbb->edges[THEN].BBptr;
|
||||||
e = pbb->edges[ELSE].BBptr;
|
e = pbb->edges[ELSE].BBptr;
|
||||||
|
|
||||||
/* Check along the THEN path */
|
/* 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;
|
obb2 = t->edges[THEN].BBptr;
|
||||||
if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&
|
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;
|
*off = obb2->start - i;
|
||||||
*arc = THEN;
|
*arc = THEN;
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check along the ELSE path */
|
/* Check along the ELSE path */
|
||||||
else if ((e->length == 1) && (e->nodeType == TWO_BRANCH) &&
|
else if ((e->length == 1) && (e->nodeType == TWO_BRANCH) &&
|
||||||
(e->numInEdges == 1))
|
(e->inEdges.size() == 1))
|
||||||
{
|
{
|
||||||
obb2 = e->edges[THEN].BBptr;
|
obb2 = e->edges[THEN].BBptr;
|
||||||
if ((obb2->length == 2) && (obb2->nodeType == TWO_BRANCH) &&
|
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;
|
*off = obb2->start - i;
|
||||||
*arc = ELSE;
|
*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)))
|
(isJCond ((pIcode+3)->ic.ll.opcode)))
|
||||||
{
|
{
|
||||||
*off = 2;
|
*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->inEdges.erase(newlast,tbb->inEdges.end());
|
||||||
tbb->numInEdges--; /* looses 2 arcs, gains 1 arc */
|
tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
|
||||||
tbb->inEdges.push_back(pbb);
|
|
||||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
|
||||||
|
|
||||||
/* Modify in edges of the ELSE basic block */
|
/* Modify in edges of the ELSE basic block */
|
||||||
tbb = pbb->edges[ELSE].BBptr;
|
tbb = pbb->edges[ELSE].BBptr;
|
||||||
auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
|
auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
|
||||||
assert(iter!=tbb->inEdges.end());
|
assert(iter!=tbb->inEdges.end());
|
||||||
tbb->inEdges.erase(iter);
|
tbb->inEdges.erase(iter); /* looses 1 arc */
|
||||||
tbb->numInEdges--; /* looses 1 arc */
|
|
||||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
|
||||||
/* Update icode index */
|
/* Update icode index */
|
||||||
(*idx) += 5;
|
(*idx) += 5;
|
||||||
}
|
}
|
||||||
@ -127,9 +123,7 @@ static void longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
|||||||
/* Modify in edges of target basic block */
|
/* Modify in edges of target basic block */
|
||||||
auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
|
auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
|
||||||
assert(iter!=tbb->inEdges.end());
|
assert(iter!=tbb->inEdges.end());
|
||||||
tbb->inEdges.erase(iter);
|
tbb->inEdges.erase(iter); /* looses 1 arc */
|
||||||
tbb->numInEdges--; /* looses 1 arc */
|
|
||||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
|
||||||
|
|
||||||
/* Modify in edges of the ELSE basic block */
|
/* Modify in edges of the ELSE basic block */
|
||||||
tbb = obb2->edges[ELSE].BBptr;
|
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->inEdges.erase(newlast,tbb->inEdges.end());
|
||||||
tbb->numInEdges--; /* looses 2 arcs, gains 1 arc */
|
tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
|
||||||
tbb->inEdges.push_back(pbb);
|
|
||||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
|
||||||
|
|
||||||
/* Modify out edge of header basic block */
|
/* Modify out edge of header basic block */
|
||||||
pbb->edges[ELSE].BBptr = tbb;
|
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 */
|
/* Create new HLI_JCOND and condition */
|
||||||
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+off+1)->ic.ll.opcode-iJB]);
|
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+off+1)->ic.ll.opcode-iJB]);
|
||||||
(pIcode+1)->setJCond(lhs);
|
(pIcode+1)->setJCond(lhs);
|
||||||
copyDU (pIcode+1, pIcode, eUSE, eUSE);
|
(pIcode+1)->copyDU(*pIcode, eUSE, eUSE);
|
||||||
(pIcode+1)->du.use |= (pIcode+off)->du.use;
|
(pIcode+1)->du.use |= (pIcode+off)->du.use;
|
||||||
|
|
||||||
/* Update statistics */
|
/* Update statistics */
|
||||||
@ -181,7 +173,7 @@ static void longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
|||||||
/* Form conditional expression */
|
/* Form conditional expression */
|
||||||
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+3)->ic.ll.opcode - iJB]);
|
lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+3)->ic.ll.opcode - iJB]);
|
||||||
(pIcode+1)->setJCond(lhs);
|
(pIcode+1)->setJCond(lhs);
|
||||||
copyDU (pIcode+1, pIcode, eUSE, eUSE);
|
(pIcode+1)->copyDU (*pIcode, eUSE, eUSE);
|
||||||
(pIcode+1)->du.use |= (pIcode+2)->du.use;
|
(pIcode+1)->du.use |= (pIcode+2)->du.use;
|
||||||
|
|
||||||
/* Adjust outEdges[0] to the new target basic block */
|
/* 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());
|
assert(iter!=tbb->inEdges.end());
|
||||||
tbb->inEdges.erase(iter);
|
tbb->inEdges.erase(iter);
|
||||||
|
|
||||||
if ((pIcode+3)->ic.ll.opcode == iJE)
|
if ((pIcode+3)->ic.ll.opcode != iJE)
|
||||||
tbb->numInEdges--; /* looses 1 arc */
|
tbb->inEdges.push_back(pbb); /* iJNE => replace arc */
|
||||||
else /* iJNE => replace arc */
|
|
||||||
tbb->inEdges.push_back(pbb);
|
|
||||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
|
||||||
|
|
||||||
/* Modify ELSE out edge of header basic block */
|
/* Modify ELSE out edge of header basic block */
|
||||||
tbb = obb1->edges[ELSE].BBptr;
|
tbb = obb1->edges[ELSE].BBptr;
|
||||||
@ -215,9 +204,8 @@ static void longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
|
|||||||
tbb->inEdges.erase(iter);
|
tbb->inEdges.erase(iter);
|
||||||
if ((pIcode+3)->ic.ll.opcode == iJE) /* replace */
|
if ((pIcode+3)->ic.ll.opcode == iJE) /* replace */
|
||||||
tbb->inEdges.push_back(pbb);
|
tbb->inEdges.push_back(pbb);
|
||||||
else
|
// else
|
||||||
tbb->numInEdges--; /* iJNE => looses 1 arc */
|
// tbb->numInEdges--; /* iJNE => looses 1 arc */
|
||||||
assert(tbb->inEdges.size()==tbb->numInEdges);
|
|
||||||
|
|
||||||
|
|
||||||
/* Update statistics */
|
/* Update statistics */
|
||||||
@ -493,7 +481,7 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
|
|||||||
lhs = COND_EXPR::boolOp (lhs, rhs,
|
lhs = COND_EXPR::boolOp (lhs, rhs,
|
||||||
condOpJCond[(pIcode+1)->ic.ll.opcode - iJB]);
|
condOpJCond[(pIcode+1)->ic.ll.opcode - iJB]);
|
||||||
(pIcode+1)->setJCond(lhs);
|
(pIcode+1)->setJCond(lhs);
|
||||||
copyDU (pIcode+1, pIcode, eUSE, eUSE);
|
(pIcode+1)->copyDU(*pIcode, eUSE, eUSE);
|
||||||
pIcode->invalidate();
|
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);
|
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
||||||
if(found_iter!=pqH.end())
|
if(found_iter!=pqH.end())
|
||||||
{
|
{
|
||||||
pI->numOutEdges -= (byte)(*found_iter)->numInEdges - 1;
|
pI->numOutEdges -= (byte)(*found_iter)->inEdges.size() - 1;
|
||||||
pqH.erase(found_iter);
|
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
|
/* Finds the intervals of graph derivedGi->Gi and places them in the list
|
||||||
* of intervals derivedGi->Ii.
|
* of intervals derivedGi->Ii.
|
||||||
* Algorithm by M.S.Hecht. */
|
* Algorithm by M.S.Hecht. */
|
||||||
void derSeq_Entry::findIntervals ()
|
void derSeq_Entry::findIntervals (Function *c)
|
||||||
{
|
{
|
||||||
interval *pI, /* Interval being processed */
|
interval *pI, /* Interval being processed */
|
||||||
*J; /* ^ last interval in derivedGi->Ii */
|
*J; /* ^ last interval in derivedGi->Ii */
|
||||||
@ -112,7 +112,7 @@ void derSeq_Entry::findIntervals ()
|
|||||||
|
|
||||||
appendQueue (H, Gi); /* H = {first node of G} */
|
appendQueue (H, Gi); /* H = {first node of G} */
|
||||||
Gi->beenOnH = TRUE;
|
Gi->beenOnH = TRUE;
|
||||||
Gi->reachingInt = BB::Create(); /* ^ empty BB */
|
Gi->reachingInt = BB::Create(0,"",c); /* ^ empty BB */
|
||||||
|
|
||||||
/* Process header nodes list H */
|
/* Process header nodes list H */
|
||||||
while (!H.empty())
|
while (!H.empty())
|
||||||
@ -185,10 +185,9 @@ static void displayIntervals (interval *pI)
|
|||||||
while (nodePtr!=pI->nodes.end())
|
while (nodePtr!=pI->nodes.end())
|
||||||
{
|
{
|
||||||
if ((*nodePtr)->correspInt == NULL) /* real BBs */
|
if ((*nodePtr)->correspInt == NULL) /* real BBs */
|
||||||
printf (" Node: %ld\n", (*nodePtr)->start);
|
printf (" Node: %ld\n", (*nodePtr)->begin());
|
||||||
else /* BBs represent intervals */
|
else /* BBs represent intervals */
|
||||||
printf (" Node (corresp int): %d\n",
|
printf (" Node (corresp int): %d\n", (*nodePtr)->correspInt->numInt);
|
||||||
(*nodePtr)->correspInt->numInt);
|
|
||||||
++nodePtr;
|
++nodePtr;
|
||||||
}
|
}
|
||||||
pI = pI->next;
|
pI = pI->next;
|
||||||
@ -240,7 +239,7 @@ derSeq_Entry::~derSeq_Entry()
|
|||||||
|
|
||||||
/* Finds the next order graph of derivedGi->Gi according to its intervals
|
/* Finds the next order graph of derivedGi->Gi according to its intervals
|
||||||
* (derivedGi->Ii), and places it in derivedGi->next->Gi. */
|
* (derivedGi->Ii), and places it in derivedGi->next->Gi. */
|
||||||
static boolT nextOrderGraph (derSeq *derivedGi)
|
bool Function::nextOrderGraph (derSeq *derivedGi)
|
||||||
{
|
{
|
||||||
interval *Ii; /* Interval being processed */
|
interval *Ii; /* Interval being processed */
|
||||||
BB *BBnode, /* New basic block of intervals */
|
BB *BBnode, /* New basic block of intervals */
|
||||||
@ -263,7 +262,7 @@ static boolT nextOrderGraph (derSeq *derivedGi)
|
|||||||
while (Ii)
|
while (Ii)
|
||||||
{
|
{
|
||||||
i = 0;
|
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 = bbs.back();
|
||||||
BBnode->correspInt = Ii;
|
BBnode->correspInt = Ii;
|
||||||
const queue &listIi(Ii->nodes);
|
const queue &listIi(Ii->nodes);
|
||||||
@ -307,7 +306,7 @@ static boolT nextOrderGraph (derSeq *derivedGi)
|
|||||||
if(iter==bbs.end())
|
if(iter==bbs.end())
|
||||||
fatalError (INVALID_INT_BB);
|
fatalError (INVALID_INT_BB);
|
||||||
edge.BBptr = *iter;
|
edge.BBptr = *iter;
|
||||||
(*iter)->numInEdges++;
|
(*iter)->inEdges.push_back(0);
|
||||||
(*iter)->inEdgeCount++;
|
(*iter)->inEdgeCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,7 +318,7 @@ static boolT nextOrderGraph (derSeq *derivedGi)
|
|||||||
/* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
|
/* Finds the derived sequence of the graph derivedG->Gi (ie. cfg).
|
||||||
* Constructs the n-th order graph and places all the intermediate graphs
|
* Constructs the n-th order graph and places all the intermediate graphs
|
||||||
* in the derivedG list sequence. */
|
* in the derivedG list sequence. */
|
||||||
static byte findDerivedSeq (derSeq *derivedGi)
|
byte Function::findDerivedSeq (derSeq *derivedGi)
|
||||||
{
|
{
|
||||||
BB *Gi; /* Current derived sequence graph */
|
BB *Gi; /* Current derived sequence graph */
|
||||||
|
|
||||||
@ -328,7 +327,7 @@ static byte findDerivedSeq (derSeq *derivedGi)
|
|||||||
while (! trivialGraph (Gi))
|
while (! trivialGraph (Gi))
|
||||||
{
|
{
|
||||||
/* Find the intervals of Gi and place them in derivedGi->Ii */
|
/* 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 */
|
/* Create Gi+1 and check if it is equivalent to Gi */
|
||||||
if (! nextOrderGraph (derivedGi))
|
if (! nextOrderGraph (derivedGi))
|
||||||
@ -346,7 +345,7 @@ static byte findDerivedSeq (derSeq *derivedGi)
|
|||||||
// derivedGi->next = NULL;
|
// derivedGi->next = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
derivedGi->back().findIntervals ();
|
derivedGi->back().findIntervals (this);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -126,8 +126,8 @@ static struct {
|
|||||||
{ none1, none2, OP386 , iZERO , 0 , }, /* 67 */
|
{ none1, none2, OP386 , iZERO , 0 , }, /* 67 */
|
||||||
{ data2, none2, NO_SRC , iPUSH , 0 , }, /* 68 */
|
{ data2, none2, NO_SRC , iPUSH , 0 , }, /* 68 */
|
||||||
{ modrm, data2, TO_REG | NSP , iIMUL , Sf | Zf | Cf, }, /* 69 */
|
{ modrm, data2, TO_REG | NSP , iIMUL , Sf | Zf | Cf, }, /* 69 */
|
||||||
{ data1, none2, S | NO_SRC , iPUSH , 0 , }, /* 6A */
|
{ data1, none2, S_EXT | NO_SRC , iPUSH , 0 , }, /* 6A */
|
||||||
{ modrm, data1, TO_REG | NSP | S , iIMUL , Sf | Zf | Cf, }, /* 6B */
|
{ 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 | B|IM_OPS , iINS , 0 , Df }, /* 6C */
|
||||||
{ strop, memImp, NOT_HLL | IM_OPS , iINS , 0 , Df }, /* 6D */
|
{ strop, memImp, NOT_HLL | IM_OPS , iINS , 0 , Df }, /* 6D */
|
||||||
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS , 0 , Df }, /* 6E */
|
{ strop, memImp, NOT_HLL | B|IM_OPS , iOUTS , 0 , Df }, /* 6E */
|
||||||
@ -151,7 +151,7 @@ static struct {
|
|||||||
{ immed, data1, B , iZERO , 0 , }, /* 80 */
|
{ immed, data1, B , iZERO , 0 , }, /* 80 */
|
||||||
{ immed, data2, NSP , iZERO , 0 , }, /* 81 */
|
{ immed, data2, NSP , iZERO , 0 , }, /* 81 */
|
||||||
{ immed, data1, B , iZERO , 0 , }, /* 82 */ /* ?? */
|
{ 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 | B , iTEST , Sf | Zf | Cf, }, /* 84 */
|
||||||
{ modrm, none2, TO_REG | NSP , iTEST , Sf | Zf | Cf, }, /* 85 */
|
{ modrm, none2, TO_REG | NSP , iTEST , Sf | Zf | Cf, }, /* 85 */
|
||||||
{ modrm, none2, TO_REG | B , iXCHG , 0 , }, /* 86 */
|
{ 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 , }, /* 95 */
|
||||||
{ regop, axImp, 0 , iXCHG , 0 , }, /* 96 */
|
{ regop, axImp, 0 , iXCHG , 0 , }, /* 96 */
|
||||||
{ regop, axImp, 0 , iXCHG , 0 , }, /* 97 */
|
{ regop, axImp, 0 , iXCHG , 0 , }, /* 97 */
|
||||||
{ alImp, axImp, SRC_B | S , iSIGNEX,0 , }, /* 98 */
|
{ alImp, axImp, SRC_B | S_EXT , iSIGNEX,0 , }, /* 98 */
|
||||||
{axSrcIm, axImp, IM_DST | S , iSIGNEX,0 , }, /* 99 */
|
{axSrcIm, axImp, IM_DST | S_EXT , iSIGNEX,0 , }, /* 99 */
|
||||||
{ dispF, none2, 0 , iCALLF ,0 , }, /* 9A */
|
{ dispF, none2, 0 , iCALLF ,0 , }, /* 9A */
|
||||||
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT , 0 , }, /* 9B */
|
{ none1, none2, FLOAT_OP| NO_OPS , iWAIT , 0 , }, /* 9B */
|
||||||
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF, 0 , }, /* 9C */
|
{ none1, none2, NOT_HLL | NO_OPS , iPUSHF, 0 , }, /* 9C */
|
||||||
@ -658,7 +658,7 @@ static void arith(Int i)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void data1(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++;
|
*pInst++;
|
||||||
pIcode->ic.ll.flg |= I;
|
pIcode->ic.ll.flg |= I;
|
||||||
}
|
}
|
||||||
|
|||||||
156
src/udm.cpp
156
src/udm.cpp
@ -15,6 +15,54 @@ static void displayDfs(BB * pBB);
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* udm
|
* 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)
|
void udm(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -22,73 +70,21 @@ void udm(void)
|
|||||||
* icodes to high-level ones */
|
* icodes to high-level ones */
|
||||||
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
|
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
|
||||||
{
|
{
|
||||||
|
iter->buildCFG();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Data flow analysis - eliminate condition codes, extraneous registers
|
/* Data flow analysis - eliminate condition codes, extraneous registers
|
||||||
* and intermediate instructions. Find expressions by forward
|
* and intermediate instructions. Find expressions by forward
|
||||||
* substitution algorithm */
|
* substitution algorithm */
|
||||||
pProcList.front().dataFlow (0);
|
pProcList.front().dataFlow (0);
|
||||||
derSeq *derivedG=0;
|
|
||||||
|
|
||||||
/* Control flow analysis - structuring algorithm */
|
/* Control flow analysis - structuring algorithm */
|
||||||
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
|
for (auto iter = pProcList.rbegin(); iter!=pProcList.rend(); ++iter)
|
||||||
{
|
{
|
||||||
|
iter->controlFlowAnalysis();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
* displayCFG - Displays the Basic Block list
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -102,58 +98,8 @@ void Function::displayCFG()
|
|||||||
for (auto iter = cfg.begin(); iter!=cfg.end(); ++iter)
|
for (auto iter = cfg.begin(); iter!=cfg.end(); ++iter)
|
||||||
{
|
{
|
||||||
pBB = *iter;
|
pBB = *iter;
|
||||||
printf("\nnode type = %s, ", s_nodeType[pBB->nodeType]);
|
(*iter)->display();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* 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"
|
#include "dcc.h"
|
||||||
|
|
||||||
|
|
||||||
long LMOD@ (long arg0, int arg2int arg3)
|
long LMOD@ (long arg0, int arg2, int arg3)
|
||||||
/* Takes 8 bytes of parameters.
|
/* Takes 8 bytes of parameters.
|
||||||
* Runtime support routine of the compiler.
|
* Runtime support routine of the compiler.
|
||||||
* Untranslatable routine. Assembler provided.
|
* 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"
|
#include "dcc.h"
|
||||||
|
|
||||||
|
|
||||||
long LMOD@ (long arg0, int arg2int arg3)
|
long LMOD@ (long arg0, int arg2, int arg3)
|
||||||
/* Takes 8 bytes of parameters.
|
/* Takes 8 bytes of parameters.
|
||||||
* Runtime support routine of the compiler.
|
* Runtime support routine of the compiler.
|
||||||
* Untranslatable routine. Assembler provided.
|
* 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