extracted FunctionCfg as it's own class

This commit is contained in:
Artur K 2012-07-15 16:52:59 +02:00
parent 5087a051b5
commit c19231a1bd
28 changed files with 315 additions and 291 deletions

View File

@ -3,7 +3,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
OPTION(dcc_build_tests "Enable unit tests." OFF) OPTION(dcc_build_tests "Enable unit tests." OFF)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS)
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)
@ -14,7 +14,7 @@ ELSE()
ENDIF() ENDIF()
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH}) SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
include(cotire)
FIND_PACKAGE(LLVM) FIND_PACKAGE(LLVM)
FIND_PACKAGE(Boost) FIND_PACKAGE(Boost)
IF(dcc_build_tests) IF(dcc_build_tests)
@ -59,6 +59,7 @@ set(dcc_LIB_SOURCES
src/idioms/shift_idioms.cpp src/idioms/shift_idioms.cpp
src/idioms/xor_idioms.cpp src/idioms/xor_idioms.cpp
src/locident.cpp src/locident.cpp
src/liveness_set.cpp
src/parser.cpp src/parser.cpp
src/perfhlib.cpp src/perfhlib.cpp
src/procs.cpp src/procs.cpp
@ -110,11 +111,11 @@ SOURCE_GROUP(Source FILES ${dcc_SOURCES})
SOURCE_GROUP(Headers FILES ${dcc_HEADERS}) SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS}) ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
cotire(dcc_lib)
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS}) ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
ADD_DEPENDENCIES(dcc_original dcc_lib) ADD_DEPENDENCIES(dcc_original dcc_lib)
TARGET_LINK_LIBRARIES(dcc_original dcc_lib disasm_s ${REQ_LLVM_LIBRARIES}) TARGET_LINK_LIBRARIES(dcc_original dcc_lib disasm_s ${REQ_LLVM_LIBRARIES})
if(dcc_build_tests) if(dcc_build_tests)
ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(src)
endif() endif()

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
cd bld #cd bld
make -j5 #make -j5
cd .. #cd ..
./test_use_base.sh ./test_use_base.sh
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/ ./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/

View File

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
./test_use_all.sh ./test_use_all.sh
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/ ./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/

View File

@ -5,7 +5,7 @@
#include <string> #include <string>
#include <llvm/ADT/ilist.h> #include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h> #include <llvm/ADT/ilist_node.h>
#include <boost/range.hpp> #include <boost/range/iterator_range.hpp>
#include "icode.h" #include "icode.h"
#include "types.h" #include "types.h"
#include "graph.h" #include "graph.h"
@ -27,10 +27,9 @@ struct TYPEADR_TYPE
TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v) TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v)
{} {}
}; };
struct BB : public llvm::ilist_node<BB> struct BB : public llvm::ilist_node<BB>
{ {
friend struct Function;
private: private:
BB(const BB&); BB(const BB&);
BB() : nodeType(0),traversed(DFS_NONE), BB() : nodeType(0),traversed(DFS_NONE),
@ -46,6 +45,7 @@ private:
//friend class SymbolTableListTraits<BB, Function>; //friend class SymbolTableListTraits<BB, Function>;
typedef boost::iterator_range<iICODE> rCODE; typedef boost::iterator_range<iICODE> rCODE;
rCODE instructions; rCODE instructions;
rCODE &my_range() {return instructions;}
public: public:
struct ValidFunctor struct ValidFunctor
@ -77,29 +77,25 @@ public:
interval *inInterval; /* Node's interval */ interval *inInterval; /* Node's interval */
/* For derived sequence construction */ /* For derived sequence construction */
interval *correspInt; /* Corresponding interval in interval *correspInt; //!< Corresponding interval in derived graph Gi-1
* derived graph Gi-1 */ // For live register analysis
// LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b))
/* For live register analysis LivenessSet liveUse; /* LiveUse(b) */
* LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) */ LivenessSet def; /* Def(b) */
std::bitset<32> liveUse; /* LiveUse(b) */ LivenessSet liveIn; /* LiveIn(b) */
std::bitset<32> def; /* Def(b) */ LivenessSet liveOut; /* LiveOut(b) */
std::bitset<32> liveIn; /* LiveIn(b) */
std::bitset<32> liveOut; /* LiveOut(b) */
/* For structuring analysis */ /* For structuring analysis */
int dfsFirstNum; /* DFS #: first visit of node */ int dfsFirstNum; /* DFS #: first visit of node */
int dfsLastNum; /* DFS #: last visit of node */ int dfsLastNum; /* DFS #: last visit of node */
int immedDom; /* Immediate dominator (dfsLast int immedDom; /* Immediate dominator (dfsLast index) */
* index) */
int ifFollow; /* node that ends the if */ int ifFollow; /* node that ends the if */
int loopType; /* Type of loop (if any) */ int loopType; /* Type of loop (if any) */
int latchNode; /* latching node of the loop */ int latchNode; /* latching node of the loop */
size_t numBackEdges; /* # of back edges */ size_t numBackEdges; /* # of back edges */
int loopHead; /* most nested loop head to which this node belongs (dfsLast) */ int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
int loopFollow; /* node that follows the loop */ int loopFollow; /* node that follows the loop */
int caseHead; /* most nested case to which this int caseHead; /* most nested case to which this node belongs (dfsLast) */
node belongs (dfsLast) */
int caseTail; /* tail node for the case */ int caseTail; /* tail node for the case */
int index; /* Index, used in several ways */ int index; /* Index, used in several ways */
@ -134,7 +130,7 @@ public:
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode); void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
private: private:
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at); bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);
void ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode); void ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode);
bool isEndOfPath(int latch_node_idx) const; bool isEndOfPath(int latch_node_idx) const;
Function *Parent; Function *Parent;

View File

@ -86,7 +86,26 @@ struct JumpTable
size_t entrySize() { return 2;} size_t entrySize() { return 2;}
void pruneEntries(uint16_t cs); void pruneEntries(uint16_t cs);
}; };
class FunctionCfg
{
std::list<BB*> m_listBB; /* Ptr. to BB list/CFG */
public:
typedef std::list<BB*>::iterator iterator;
iterator begin() {
return m_listBB.begin();
}
iterator end() {
return m_listBB.end();
}
BB * &front() { return m_listBB.front();}
void nodeSplitting()
{
/* Converts the irreducible graph G into an equivalent reducible one, by
* means of node splitting. */
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
}
void push_back(BB *v) { m_listBB.push_back(v);}
};
struct Function : public llvm::ilist_node<Function> struct Function : public llvm::ilist_node<Function>
{ {
typedef llvm::iplist<BB> BasicBlockListType; typedef llvm::iplist<BB> BasicBlockListType;
@ -109,6 +128,7 @@ public:
/* Icodes and control flow graph */ /* Icodes and control flow graph */
CIcodeRec Icode; /* Object with ICODE records */ CIcodeRec Icode; /* Object with ICODE records */
FunctionCfg m_actual_cfg;
std::list<BB*> m_cfg; /* Ptr. to BB list/CFG */ std::list<BB*> m_cfg; /* Ptr. to BB list/CFG */
std::vector<BB*> m_dfsLast; std::vector<BB*> m_dfsLast;
std::list<BB*> heldBBs; std::list<BB*> heldBBs;
@ -118,8 +138,8 @@ public:
bool hasCase; /* Procedure has a case node */ bool hasCase; /* Procedure has a case node */
/* For interprocedural live analysis */ /* For interprocedural live analysis */
std::bitset<32> liveIn; /* Registers used before defined */ LivenessSet liveIn; /* Registers used before defined */
std::bitset<32> liveOut; /* Registers that may be used in successors */ LivenessSet liveOut; /* Registers that may be used in successors */
bool liveAnal; /* Procedure has been analysed already */ bool liveAnal; /* Procedure has been analysed already */
Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0), Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
@ -140,7 +160,7 @@ public:
void writeProcComments(); void writeProcComments();
void lowLevelAnalysis(); void lowLevelAnalysis();
void bindIcodeOff(); void bindIcodeOff();
void dataFlow(std::bitset<32> &liveOut); void dataFlow(LivenessSet &liveOut);
void compressCFG(); void compressCFG();
void highLevelGen(); void highLevelGen();
void structure(derSeq *derivedG); void structure(derSeq *derivedG);
@ -166,7 +186,7 @@ public:
void displayStats(); void displayStats();
void processHliCall(COND_EXPR *exp, iICODE picode); void processHliCall(COND_EXPR *exp, iICODE picode);
void preprocessReturnDU(std::bitset<32> &_liveOut); void preprocessReturnDU(LivenessSet &_liveOut);
protected: protected:
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table); void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
@ -190,7 +210,7 @@ protected:
void findExps(); void findExps();
void genDU1(); void genDU1();
void elimCondCodes(); void elimCondCodes();
void liveRegAnalysis(std::bitset<32> &in_liveOut); void liveRegAnalysis(LivenessSet &in_liveOut);
void findIdioms(); void findIdioms();
void propLong(); void propLong();
void genLiveKtes(); void genLiveKtes();

View File

@ -7,8 +7,8 @@
#pragma once #pragma once
#include <cstring> #include <cstring>
#include <list> #include <list>
#include <boost/range/iterator_range.hpp>
#include "Enums.h" #include "Enums.h"
#include <boost/range.hpp>
static const int operandSize=20; static const int operandSize=20;
/* The following definitions and types define the Conditional Expression /* The following definitions and types define the Conditional Expression
* attributed syntax tree, as defined by the following EBNF: * attributed syntax tree, as defined by the following EBNF:

View File

@ -62,10 +62,10 @@ typedef struct { /* Command line option flags */
extern OPTION option; /* Command line options */ extern OPTION option; /* Command line options */
#include "BinaryImage.h" #include "BinaryImage.h"
extern std::bitset<32> duReg[30]; /* def/use bits for registers */ extern LivenessSet duReg[30]; /* def/use bits for registers */
//extern uint32_t duReg[30]; /* def/use bits for registers */ //extern uint32_t duReg[30]; /* def/use bits for registers */
extern std::bitset<32> maskDuReg[30]; /* masks off du bits for regs */ extern LivenessSet maskDuReg[30]; /* masks off du bits for regs */
/* Registers used by icode instructions */ /* Registers used by icode instructions */

View File

@ -1,9 +1,10 @@
/**************************************************************************** /*
* dcc project disassembler header ***************************************************************************
* (C) Mike van Emmerik dcc project disassembler header
****************************************************************************/ (C) Mike van Emmerik
***************************************************************************
*/
#pragma once #pragma once
#include <sstream>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include "bundle.h" #include "bundle.h"
@ -32,24 +33,6 @@ public:
#define EXT 0x100 /* "Extended" flag */ #define EXT 0x100 /* "Extended" flag */
#ifdef __MSDOS__
#define KEY_DOWN EXT+'P'
#define KEY_LEFT EXT+'K'
#define KEY_UP EXT+'H'
#define KEY_RIGHT EXT+'M'
#define KEY_NPAGE EXT+'Q'
#define KEY_PPAGE EXT+'I'
#endif
#ifdef _CONSOLE
#define KEY_DOWN 0x50 /* Same as keypad scancodes */
#define KEY_LEFT 0x4B
#define KEY_UP 0x48
#define KEY_RIGHT 0x4D
#define KEY_NPAGE 0x51
#define KEY_PPAGE 0x49
#endif
#ifdef __UNIX__ #ifdef __UNIX__
#define KEY_DOWN EXT+'B' #define KEY_DOWN EXT+'B'
#define KEY_LEFT EXT+'D' #define KEY_LEFT EXT+'D'

View File

@ -1,8 +1,11 @@
/*************************************************************************** /*
=**************************************************************************
* File : dosdcc.h * File : dosdcc.h
* Purpose : include file for files decompiled by dcc. * Purpose : include file for files decompiled by dcc.
* Copyright (c) Cristina Cifuentes - QUT - 1992 * Copyright (c) Cristina Cifuentes - QUT - 1992
**************************************************************************/ *************************************************************************
*/
/* Type definitions for intel 80x86 architecture */ /* Type definitions for intel 80x86 architecture */
typedef unsigned int uint16_t; /* 16 bits */ typedef unsigned int uint16_t; /* 16 bits */

View File

@ -1,10 +1,13 @@
/***************************************************************************** /*
****************************************************************************
* CFG, BB and interval related definitions * CFG, BB and interval related definitions
* (C) Cristina Cifuentes * ( C ) Cristina Cifuentes
****************************************************************************/ ****************************************************************************
*/
#pragma once #pragma once
#include <stdint.h>
#include <list> #include <list>
#include <vector>
struct Function; 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 */
@ -55,6 +58,7 @@ enum eNodeHeaderType
#define ELSE 1 /* else edge */ #define ELSE 1 /* else edge */
/* Basic Block (BB) flags */ /* Basic Block (BB) flags */
#define INVALID_BB 0x0001 /* BB is not valid any more */ #define INVALID_BB 0x0001 /* BB is not valid any more */
#define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */ #define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */
@ -76,6 +80,7 @@ struct interval
currNode=nodes.end(); currNode=nodes.end();
next=0; next=0;
} }
void appendNodeInt(queue &pqH, BB *node);
}; };
@ -83,6 +88,7 @@ struct interval
struct derSeq_Entry struct derSeq_Entry
{ {
BB * Gi; /* Graph pointer */ BB * Gi; /* Graph pointer */
std::list<interval *> m_intervals;
interval * Ii; /* Interval list of Gi */ interval * Ii; /* Interval list of Gi */
derSeq_Entry() : Gi(0),Ii(0) derSeq_Entry() : Gi(0),Ii(0)
{ {

View File

@ -9,12 +9,9 @@
#include <bitset> #include <bitset>
#include <llvm/ADT/ilist.h> #include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h> #include <llvm/ADT/ilist_node.h>
#include <llvm/CodeGen/MachineInstr.h>
#include <llvm/MC/MCInst.h> #include <llvm/MC/MCInst.h>
#include <llvm/MC/MCAsmInfo.h>
#include <llvm/Value.h>
#include <llvm/Instruction.h> #include <llvm/Instruction.h>
#include <boost/range.hpp> #include <boost/range/iterator_range.hpp>
#include "libdis.h" #include "libdis.h"
#include "Enums.h" #include "Enums.h"
#include "state.h" // State depends on INDEXBASE, but later need STATE #include "state.h" // State depends on INDEXBASE, but later need STATE
@ -32,7 +29,45 @@ typedef std::list<ICODE>::iterator iICODE;
typedef std::list<ICODE>::reverse_iterator riICODE; typedef std::list<ICODE>::reverse_iterator riICODE;
typedef boost::iterator_range<iICODE> rCODE; typedef boost::iterator_range<iICODE> rCODE;
extern std::bitset<32> duReg[30]; struct LivenessSet : public std::bitset<32>
{
LivenessSet(int val=0) : std::bitset<32>(val) {}
LivenessSet(const LivenessSet &other)
{
(std::bitset<32> &)*this = (std::bitset<32> &)other;
}
LivenessSet(const std::bitset<32> &other)
{
(std::bitset<32> &)*this = other;
}
// LivenessSet(LivenessSet &&other) : LivenessSet()
// {
// swap(*this,other);
// }
LivenessSet &operator=(LivenessSet other)
{
swap(*this,other);
return *this;
}
friend void swap(LivenessSet& first, LivenessSet& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// by swapping the members of two classes,
// the two classes are effectively swapped
swap((std::bitset<32> &)first, (std::bitset<32> &)second);
}
LivenessSet &setReg(int r);
LivenessSet &addReg(int r);
bool testReg(int r)
{
return test(r-rAX);
}
};
extern LivenessSet duReg[30];
/* uint8_t and uint16_t registers */ /* uint8_t and uint16_t registers */
/* Def/use of flags - low 4 bits represent flags */ /* Def/use of flags - low 4 bits represent flags */
@ -350,14 +385,13 @@ public:
use.reset(); use.reset();
lastDefRegi.reset(); lastDefRegi.reset();
} }
std::bitset<32> def; // For Registers: position in bitset is reg index LivenessSet def; // For Registers: position in bitset is reg index
std::bitset<32> use; // For Registers: position in uint32_t is reg index LivenessSet use; // For Registers: position in uint32_t is reg index
std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB LivenessSet lastDefRegi;// Bit set if last def of this register in BB
void addDefinedAndUsed(eReg r) void addDefinedAndUsed(eReg r)
{ {
def |= duReg[r]; def.addReg(r);
use |= duReg[r]; use.addReg(r);
} }
}; };
struct DU1 struct DU1

View File

@ -73,7 +73,7 @@ public:
ostr << regName(eReg(j))<<" "; ostr << regName(eReg(j))<<" ";
} }
} }
static eReg subRegH(eReg reg); //TODO: move these into machine_x86 static eReg subRegH(eReg reg);
static eReg subRegL(eReg reg); static eReg subRegL(eReg reg);
static bool isMemOff(eReg r); static bool isMemOff(eReg r);

View File

@ -3,10 +3,7 @@
hashing functions hashing functions
* (C) Mike van Emmerik * (C) Mike van Emmerik
*/ */
#include <stdint.h>
//#define bool unsigned char
#define uint8_t unsigned char
#define uint16_t unsigned short
/* Prototypes */ /* Prototypes */
void hashCleanup(void); /* Frees memory allocated by hashParams() */ void hashCleanup(void); /* Frees memory allocated by hashParams() */

View File

@ -36,7 +36,7 @@ BB *BB::Create(const rCODE &r,uint8_t _nodeType, Function *parent)
//setInBB should automatically handle if our range is empty //setInBB should automatically handle if our range is empty
parent->Icode.SetInBB(pnewBB->instructions, pnewBB); parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
parent->heldBBs.push_back(pnewBB); parent->heldBBs.push_back(pnewBB);
parent->m_cfg.push_back(pnewBB); parent->m_actual_cfg.push_back(pnewBB);
pnewBB->Parent = parent; pnewBB->Parent = parent;
} }
@ -127,13 +127,11 @@ void BB::displayDfs()
pb.BBptr->displayDfs(); pb.BBptr->displayDfs();
} }
} }
/* Recursive procedure that writes the code for the given procedure, pointed /** Recursive procedure that writes the code for the given procedure, pointed
* to by pBB. to by pBB.
* Parameters: pBB: pointer to the cfg. \param indLevel indentation level - used for formatting.
* Icode: pointer to the Icode array for the cfg graph of the \param numLoc: last # assigned to local variables
* current procedure. */
* indLevel: indentation level - used for formatting.
* numLoc: last # assigned to local variables */
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond) ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond)
{ {
latch = pProc->m_dfsLast[this->latchNode]; latch = pProc->m_dfsLast[this->latchNode];
@ -177,6 +175,7 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
case ENDLESS_TYPE: case ENDLESS_TYPE:
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n"; ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
picode = &latch->back();
} }
cCode.appendCode(ostr.str()); cCode.appendCode(ostr.str());
stats.numHLIcode += 1; stats.numHLIcode += 1;
@ -226,7 +225,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
return; return;
/* Check type of loop/node and process code */ /* Check type of loop/node and process code */
if ( loopType) /* there is a loop */ if ( loopType ) /* there is a loop */
{ {
assert(latch); assert(latch);
if (this != latch) /* loop is over several bbs */ if (this != latch) /* loop is over several bbs */
@ -391,16 +390,16 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
iICODE BB::begin() iICODE BB::begin()
{ {
return instructions.begin();//range_start; return instructions.begin();
} }
iICODE BB::end() const iICODE BB::end() const
{ {
return instructions.end();//range_end return instructions.end();
} }
ICODE &BB::back() ICODE &BB::back()
{ {
return instructions.back();//*rbegin(); return instructions.back();
} }
size_t BB::size() size_t BB::size()
@ -411,7 +410,7 @@ size_t BB::size()
ICODE &BB::front() ICODE &BB::front()
{ {
return instructions.front();//*begin(); return instructions.front();
} }
riICODE BB::rbegin() riICODE BB::rbegin()

View File

@ -43,15 +43,14 @@ void ICODE::setRegDU (eReg regi, operDu du_in)
switch (du_in) switch (du_in)
{ {
case eDEF: case eDEF:
du.def |= duReg[regi]; du.def.addReg(regi);
du1.numRegsDef++; du1.numRegsDef++;
break; break;
case eUSE: case eUSE:
du.use |= duReg[regi]; du.use.addReg(regi);
break; break;
case USE_DEF: case USE_DEF:
du.def |= duReg[regi]; du.addDefinedAndUsed(regi);
du.use |= duReg[regi];
du1.numRegsDef++; du1.numRegsDef++;
break; break;
case NONE: /* do nothing */ case NONE: /* do nothing */

View File

@ -266,7 +266,7 @@ void Function::codeGen (std::ostream &fs)
} }
else /* generate C */ else /* generate C */
{ {
m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT); m_actual_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);
} }
cCode.appendCode( "}\n\n"); cCode.appendCode( "}\n\n");

View File

@ -337,8 +337,7 @@ void SetupLibCheck(void)
PatLen, /* The length of the pattern to be hashed */ PatLen, /* The length of the pattern to be hashed */
256, /* The character set of the pattern (0-FF) */ 256, /* The character set of the pattern (0-FF) */
0, /* Minimum pattern character value */ 0, /* Minimum pattern character value */
numVert); /* Specifies c, the sparseness of the graph. numVert); /* Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details */
See Czech, Havas and Majewski for details */
T1base = g_pattern_hasher.readT1(); T1base = g_pattern_hasher.readT1();
T2base = g_pattern_hasher.readT2(); T2base = g_pattern_hasher.readT2();
g = g_pattern_hasher.readG(); g = g_pattern_hasher.readG();
@ -462,8 +461,7 @@ bool LibCheck(Function & pProc)
//memmove(pat, &prog.Image[fileOffset], PATLEN); //memmove(pat, &prog.Image[fileOffset], PATLEN);
fixWildCards(pat); /* Fix wild cards in the copy */ fixWildCards(pat); /* Fix wild cards in the copy */
h = g_pattern_hasher.hash(pat); /* Hash the found proc */ h = g_pattern_hasher.hash(pat); /* Hash the found proc */
/* We always have to compare keys, because the hash function will /* We always have to compare keys, because the hash function will always return a valid index */
always return a valid index */
if (memcmp(ht[h].htPat, pat, PATLEN) == 0) if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
{ {
/* We have a match. Save the name, if not already set */ /* We have a match. Save the name, if not already set */
@ -494,13 +492,13 @@ bool LibCheck(Function & pProc)
pProc.flg |= PROC_IS_FUNC; pProc.flg |= PROC_IS_FUNC;
switch (pProc.retVal.type) { switch (pProc.retVal.type) {
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
pProc.liveOut = duReg[rDX] | duReg[rAX]; pProc.liveOut.setReg(rDX) |= duReg[rAX];
break; break;
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
pProc.liveOut = duReg[rAX]; pProc.liveOut.setReg(rAX);
break; break;
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
pProc.liveOut = duReg[rAL]; pProc.liveOut.setReg(rAL);
break; break;
default: default:
fprintf(stderr,"Unknown retval type %d in LibCheck\n",pProc.retVal.type); fprintf(stderr,"Unknown retval type %d in LibCheck\n",pProc.retVal.type);

View File

@ -45,7 +45,6 @@ void ExpStack::init()
expStk.clear(); expStk.clear();
} }
/* Pushes the given expression onto the local stack (expStk). */ /* Pushes the given expression onto the local stack (expStk). */
void ExpStack::push(COND_EXPR *expr) void ExpStack::push(COND_EXPR *expr)
{ {
@ -114,7 +113,7 @@ static COND_EXPR *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i,
/* Eliminates all condition codes and generates new hlIcode instructions */ /* Eliminates all condition codes and generates new hlIcode instructions */
void Function::elimCondCodes () void Function::elimCondCodes ()
{ {
// int i; // int i;
uint8_t use; /* Used flags bit vector */ uint8_t use; /* Used flags bit vector */
uint8_t def; /* Defined flags bit vector */ uint8_t def; /* Defined flags bit vector */
@ -129,15 +128,7 @@ void Function::elimCondCodes ()
auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) ); auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
for( BB * pBB : valid_reversed_bbs) for( BB * pBB : valid_reversed_bbs)
{ {
//auto reversed_instructions = pBB->range() | reversed;
// for (size_t i = 0; i < numBBs; i++)
// {
// pBB = m_dfsLast[i];
// if (pBB->flg & INVALID_BB)
// continue; /* Do not process invalid BBs */
// auto v(pBB | boost::adaptors::reversed);
// for (const ICODE &useAt : v)
// {}
for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++) for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++)
{ {
llIcode useAtOp = llIcode(useAt->ll()->getOpcode()); llIcode useAtOp = llIcode(useAt->ll()->getOpcode());
@ -234,7 +225,6 @@ void Function::elimCondCodes ()
else if (defAt == pBB->rend()) else if (defAt == pBB->rend())
{ {
reportError(DEF_NOT_FOUND,useAtOp); reportError(DEF_NOT_FOUND,useAtOp);
//fatalError (DEF_NOT_FOUND, Icode.getOpcode(useAt-1));
} }
} }
} }
@ -250,7 +240,7 @@ void Function::elimCondCodes ()
void Function::genLiveKtes () void Function::genLiveKtes ()
{ {
BB * pbb; BB * pbb;
bitset<32> liveUse, def; LivenessSet liveUse, def;
for (size_t i = 0; i < numBBs; i++) for (size_t i = 0; i < numBBs; i++)
{ {
@ -276,15 +266,15 @@ void Function::genLiveKtes ()
/* Generates the liveIn() and liveOut() sets for each basic block via an /* Generates the liveIn() and liveOut() sets for each basic block via an
* iterative approach. * iterative approach.
* Propagates register usage information to the procedure call. */ * Propagates register usage information to the procedure call. */
void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) void Function::liveRegAnalysis (LivenessSet &in_liveOut)
{ {
using namespace boost::adaptors; using namespace boost::adaptors;
using namespace boost::assign; using namespace boost::assign;
BB * pbb=0; /* pointer to current basic block */ //BB * pbb=0; /* pointer to current basic block */
Function * pcallee; /* invoked subroutine */ Function * pcallee; /* invoked subroutine */
//ICODE *ticode /* icode that invokes a subroutine */ //ICODE *ticode /* icode that invokes a subroutine */
; ;
std::bitset<32> prevLiveOut, /* previous live out */ LivenessSet prevLiveOut, /* previous live out */
prevLiveIn; /* previous live in */ prevLiveIn; /* previous live in */
boolT change; /* is there change in the live sets?*/ boolT change; /* is there change in the live sets?*/
@ -297,9 +287,8 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
/* Process nodes in reverse postorder order */ /* Process nodes in reverse postorder order */
change = false; change = false;
auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) ); auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
for( BB * _pbb : valid_reversed_bbs) for( BB * pbb : valid_reversed_bbs) // for each valid pbb in reversed dfs order
{ {
pbb = _pbb;//*iBB;//m_dfsLast[i-1];
/* Get current liveIn() and liveOut() sets */ /* Get current liveIn() and liveOut() sets */
prevLiveIn = pbb->liveIn; prevLiveIn = pbb->liveIn;
@ -349,10 +338,10 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
) )
pbb->liveOut = pcallee->liveOut; pbb->liveOut = pcallee->liveOut;
else else
pbb->liveOut = 0; pbb->liveOut.reset();
} }
if ((! (pcallee->flg & PROC_ISLIB)) || (pbb->liveOut != 0)) if ((! (pcallee->flg & PROC_ISLIB)) || ( pbb->liveOut.any() ))
{ {
switch (pcallee->retVal.type) { switch (pcallee->retVal.type) {
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
@ -375,28 +364,28 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
} }
/* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */ /* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
pbb->liveIn = pbb->liveUse | (pbb->liveOut & ~pbb->def); pbb->liveIn = LivenessSet(pbb->liveUse | (pbb->liveOut & ~pbb->def));
/* Check if live sets have been modified */ /* Check if live sets have been modified */
if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut)) if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
change = true; change = true;
} }
} }
BB *pbb = m_dfsLast.front();
/* Propagate liveIn(b) to procedure header */ /* Propagate liveIn(b) to procedure header */
if (pbb->liveIn != 0) /* uses registers */ if (pbb->liveIn.any()) /* uses registers */
liveIn = pbb->liveIn; liveIn = pbb->liveIn;
/* Remove any references to register variables */ /* Remove any references to register variables */
if (flg & SI_REGVAR) if (flg & SI_REGVAR)
{ {
liveIn &= maskDuReg[rSI]; liveIn.set(rSI,0);
pbb->liveIn &= maskDuReg[rSI]; pbb->liveIn.set(rSI,0);
} }
if (flg & DI_REGVAR) if (flg & DI_REGVAR)
{ {
liveIn &= maskDuReg[rDI]; liveIn.set(rDI,0);
pbb->liveIn &= maskDuReg[rDI]; pbb->liveIn.set(rDI,0);
} }
} }
@ -434,13 +423,13 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
/* Check if last definition of this register */ /* Check if last definition of this register */
if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any()) if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
start_at->du.lastDefRegi |= duReg[regi]; start_at->du.lastDefRegi.addReg(regi);
} }
else /* only 1 instruction in this basic block */ else /* only 1 instruction in this basic block */
{ {
/* Check if last definition of this register */ /* Check if last definition of this register */
if ((liveOut & duReg[regi]).any()) if ((liveOut & duReg[regi]).any())
start_at->du.lastDefRegi |= duReg[regi]; start_at->du.lastDefRegi.addReg(regi);
} }
return false; return false;
} }
@ -448,10 +437,10 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
* that are functions. The target icode is in the * that are functions. The target icode is in the
* next basic block (unoptimized code) or somewhere else * next basic block (unoptimized code) or somewhere else
* on optimized code. */ * on optimized code. */
void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode) void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
{ {
if ((picode->hl()->opcode == HLI_CALL) && if ((picode.hl()->opcode == HLI_CALL) &&
(picode->hl()->call.proc->flg & PROC_IS_FUNC)) (picode.hl()->call.proc->flg & PROC_IS_FUNC))
{ {
BB *tbb = this->edges[0].BBptr; BB *tbb = this->edges[0].BBptr;
auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level); auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level);
@ -459,7 +448,7 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
{ {
/* if used, get icode index */ /* if used, get icode index */
if ((iter->du.use & duReg[regi]).any()) if ((iter->du.use & duReg[regi]).any())
picode->du1.recordUse(defRegIdx,iter.base()); picode.du1.recordUse(defRegIdx,iter.base());
/* if defined, stop finding uses for this reg */ /* if defined, stop finding uses for this reg */
if ((iter->du.def & duReg[regi]).any()) if ((iter->du.def & duReg[regi]).any())
break; break;
@ -468,8 +457,8 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
/* if not used in this basic block, check if the /* if not used in this basic block, check if the
* register is live out, if so, make it the last * register is live out, if so, make it the last
* definition of this register */ * definition of this register */
if ( picode->du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any()) if ( picode.du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
picode->du.lastDefRegi |= duReg[regi]; picode.du.lastDefRegi.addReg(regi);
} }
} }
@ -502,7 +491,7 @@ void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
} }
} }
else /* liveOut */ else /* liveOut */
picode->du.lastDefRegi |= duReg[regi]; picode->du.lastDefRegi.addReg(regi);
} }
} }
@ -529,7 +518,7 @@ void BB::genDU1()
if(FindUseBeforeDef(regi,defRegIdx, picode.base())) if(FindUseBeforeDef(regi,defRegIdx, picode.base()))
continue; continue;
ProcessUseDefForFunc(regi, defRegIdx,picode.base()); ProcessUseDefForFunc(regi, defRegIdx,*picode);
RemoveUnusedDefs(regi, defRegIdx, picode.base()); RemoveUnusedDefs(regi, defRegIdx, picode.base());
defRegIdx++; defRegIdx++;
@ -857,8 +846,6 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>()); auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>());
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++) for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
{ {
// if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() ))
// continue;
HLTYPE &_icHl(*picode->hl()); HLTYPE &_icHl(*picode->hl());
numHlIcodes++; numHlIcodes++;
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */ if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
@ -1125,11 +1112,11 @@ void Function::findExps()
g_exp_stk.init(); g_exp_stk.init();
/* Traverse tree in dfsLast order */ /* Traverse tree in dfsLast order */
// for (i = 0; i < numBBs; i++) // for (i = 0; i < numBBs; i++)
for(BB *pbb : m_dfsLast) for(BB *pbb : m_dfsLast)
{ {
/* Process one BB */ /* Process one BB */
// pbb = m_dfsLast[i]; // pbb = m_dfsLast[i];
if (not pbb->valid()) if (not pbb->valid())
continue; continue;
pbb->findBBExps( this->localId, this); pbb->findBBExps( this->localId, this);
@ -1137,25 +1124,25 @@ void Function::findExps()
} }
} }
void Function::preprocessReturnDU(std::bitset<32> &_liveOut) void Function::preprocessReturnDU(LivenessSet &_liveOut)
{ {
if (_liveOut.any()) if (_liveOut.any())
{ {
// int idx; // int idx;
bool isAx, isBx, isCx, isDx; bool isAx, isBx, isCx, isDx;
flg |= PROC_IS_FUNC; flg |= PROC_IS_FUNC;
isAx = _liveOut.test(rAX - rAX); isAx = _liveOut.testReg(rAX);
isBx = _liveOut.test(rBX - rAX); isBx = _liveOut.testReg(rBX);
isCx = _liveOut.test(rCX - rAX); isCx = _liveOut.testReg(rCX);
isDx = _liveOut.test(rDX - rAX); isDx = _liveOut.testReg(rDX);
bool isAL = !isAx && _liveOut.test(rAL - rAX); bool isAL = !isAx && _liveOut.testReg(rAL);
bool isAH = !isAx && _liveOut.test(rAH - rAX); bool isAH = !isAx && _liveOut.testReg(rAH);
bool isBL = !isBx && _liveOut.test(rBL - rAX); bool isBL = !isBx && _liveOut.testReg(rBL);
bool isBH = !isBx && _liveOut.test(rBH - rAX); bool isBH = !isBx && _liveOut.testReg(rBH);
bool isCL = !isCx && _liveOut.test(rCL - rAX); bool isCL = !isCx && _liveOut.testReg(rCL);
bool isCH = !isCx && _liveOut.test(rCH - rAX); bool isCH = !isCx && _liveOut.testReg(rCH);
bool isDL = !isDx && _liveOut.test(rDL - rAX); bool isDL = !isDx && _liveOut.testReg(rDL);
bool isDH = !isDx && _liveOut.test(rDH - rAX); bool isDH = !isDx && _liveOut.testReg(rDH);
if(isAL && isAH) if(isAL && isAH)
{ {
isAx = true; isAx = true;
@ -1217,17 +1204,17 @@ void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
} }
} }
} }
/** Invokes procedures related with data flow analysis. Works on a procedure /** Invokes procedures related with data flow analysis.
* at a time basis. * Works on a procedure at a time basis.
* Note: indirect recursion in liveRegAnalysis is possible. */ \note indirect recursion in liveRegAnalysis is possible. */
void Function::dataFlow(std::bitset<32> &_liveOut) void Function::dataFlow(LivenessSet &_liveOut)
{ {
/* Remove references to register variables */ /* Remove references to register variables */
if (flg & SI_REGVAR) if (flg & SI_REGVAR)
_liveOut &= maskDuReg[rSI]; _liveOut.set(rSI,0);
if (flg & DI_REGVAR) if (flg & DI_REGVAR)
_liveOut &= maskDuReg[rDI]; _liveOut.set(rDI,0);
/* Function - return value register(s) */ /* Function - return value register(s) */
preprocessReturnDU(_liveOut); preprocessReturnDU(_liveOut);

View File

@ -3,10 +3,11 @@
* Loads a program into simulated main memory and builds the procedure list. * Loads a program into simulated main memory and builds the procedure list.
* (C) Cristina Cifuentes * (C) Cristina Cifuentes
****************************************************************************/ ****************************************************************************/
#define __STDC_FORMAT_MACROS
#include "dcc.h" #include "dcc.h"
#include "disassem.h" #include "disassem.h"
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -35,7 +35,7 @@ void Function::createCFG()
* 5) Repeated string instructions * 5) Repeated string instructions
* 6) End of procedure * 6) End of procedure
*/ */
int i;
BB * psBB; BB * psBB;
BB * pBB; BB * pBB;
iICODE pIcode = Icode.begin(); iICODE pIcode = Icode.begin();
@ -209,7 +209,7 @@ void Function::compressCFG()
/* First pass over BB list removes redundant jumps of the form /* First pass over BB list removes redundant jumps of the form
* (Un)Conditional -> Unconditional jump */ * (Un)Conditional -> Unconditional jump */
for (BB *pBB : m_cfg) for (BB *pBB : m_actual_cfg) //m_cfg
{ {
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH)) if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
continue; continue;
@ -231,18 +231,17 @@ void Function::compressCFG()
/* Next is a depth-first traversal merging any FALL_NODE or /* Next is a depth-first traversal merging any FALL_NODE or
* ONE_BRANCH that fall through to a node with that as their only * ONE_BRANCH that fall through to a node with that as their only
* in-edge. */ * in-edge. */
m_cfg.front()->mergeFallThrough(Icode); m_actual_cfg.front()->mergeFallThrough(Icode);
/* Remove redundant BBs created by the above compressions /* Remove redundant BBs created by the above compressions
* and allocate in-edge arrays as required. */ * and allocate in-edge arrays as required. */
stats.numBBaft = stats.numBBbef; stats.numBBaft = stats.numBBbef;
bool entry_node=true;
for(auto iter=m_cfg.begin(); iter!=m_cfg.end(); ++iter) for(BB *pBB : m_actual_cfg)
{ {
BB * pBB = *iter;
if (pBB->inEdges.empty()) if (pBB->inEdges.empty())
{ {
if (iter == m_cfg.begin()) /* Init it misses out on */ if (entry_node) /* Init it misses out on */
pBB->index = UN_INIT; pBB->index = UN_INIT;
else else
{ {
@ -254,6 +253,7 @@ void Function::compressCFG()
{ {
pBB->inEdgeCount = pBB->inEdges.size(); pBB->inEdgeCount = pBB->inEdges.size();
} }
entry_node=false;
} }
/* Allocate storage for dfsLast[] array */ /* Allocate storage for dfsLast[] array */
@ -262,7 +262,7 @@ void Function::compressCFG()
/* Now do a dfs numbering traversal and fill in the inEdges[] array */ /* Now do a dfs numbering traversal and fill in the inEdges[] array */
last = numBBs - 1; last = numBBs - 1;
m_cfg.front()->dfsNumbering(m_dfsLast, &first, &last); m_actual_cfg.front()->dfsNumbering(m_dfsLast, &first, &last);
} }

View File

@ -10,13 +10,23 @@
#include <sstream> #include <sstream>
#include "dcc.h" #include "dcc.h"
using namespace std; using namespace std;
#define ICODE_DELTA 25
/* Masks off bits set by duReg[] */ /* Masks off bits set by duReg[] */
std::bitset<32> maskDuReg[] = { 0x00, LivenessSet maskDuReg[] = { 0x00,
0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */ /* uint16_t regs */
0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F, 0xFEEFFE, //rAX
0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */ 0xFDDFFD, //rCX
0xFBB00B, //rDX
0xF77007, //rBX
0xFFFFEF, //rSP
0xFFFFDF, //rBP
0xFFFFBF, //rSI
0xFFFF7F, //rDI
0xFFFEFF,
0xFFFDFF,
0xFFFBFF,
0xFFF7FF, /* seg regs */
0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */ 0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF, 0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
0xEFFFFF, /* tmp reg */ 0xEFFFFF, /* tmp reg */

View File

@ -2,15 +2,12 @@
// (C) 1997 Mike Van Emmerik // (C) 1997 Mike Van Emmerik
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include "dcc.h" #include "dcc.h"
#include "types.h" // Common types like uint8_t, etc #include "types.h" // Common types like uint8_t, 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"
#define ICODE_DELTA 25 // Amount to allocate for new chunk
ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level; ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level;
ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level; ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level;
@ -31,9 +28,7 @@ ICODE * CIcodeRec::addIcode(ICODE *pIcode)
void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB) void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB)
{ {
for(ICODE &ic : rang) for(ICODE &ic : rang)
{
ic.setParent(pnewBB); ic.setParent(pnewBB);
}
} }
/* labelSrchRepl - Searches the icodes for instruction with label = target, and /* labelSrchRepl - Searches the icodes for instruction with label = target, and

View File

@ -16,13 +16,11 @@ bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false) ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
{ {
name[0]=0;
macro[0]=0; macro[0]=0;
memset(&id,0,sizeof(id)); memset(&id,0,sizeof(id));
} }
ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false) ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
{ {
name[0]=0;
macro[0]=0; macro[0]=0;
memset(&id,0,sizeof(id)); memset(&id,0,sizeof(id));
loc=f; loc=f;
@ -273,7 +271,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
* number in an expression record. */ * number in an expression record. */
int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset) int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset)
{ {
size_t idx; size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
const LLOperand *pmH, *pmL; const LLOperand *pmH, *pmL;
LLInst &p_ll(*pIcode->ll()); LLInst &p_ll(*pIcode->ll());
if (f == LOW_FIRST) if (f == LOW_FIRST)

View File

@ -2,7 +2,7 @@
* dcc project procedure list builder * dcc project procedure list builder
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann * (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
****************************************************************************/ ****************************************************************************/
#define __STDC_FORMAT_MACROS
#include <inttypes.h> #include <inttypes.h>
#include <string.h> #include <string.h>
#include <stdlib.h> /* For exit() */ #include <stdlib.h> /* For exit() */
@ -886,7 +886,7 @@ static void setBits(int16_t type, uint32_t start, uint32_t len)
} }
/* DU bit definitions for each reg value - including index registers */ /* DU bit definitions for each reg value - including index registers */
std::bitset<32> duReg[] = { 0x00, LivenessSet duReg[] = { 0x00,
//AH AL . . AX, BH //AH AL . . AX, BH
0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */ 0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */
0x10, 0x20, 0x40, 0x80, 0x10, 0x20, 0x40, 0x80,
@ -1066,7 +1066,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
case iDIV: case iIDIV: case iDIV: case iIDIV:
use(SRC, pIcode, this, pstate, cb); use(SRC, pIcode, this, pstate, cb);
if (cb == 1) if (cb == 1)
pIcode.du.use |= duReg[rTMP]; pIcode.du.use.addReg(rTMP);
break; break;
case iMUL: case iIMUL: case iMUL: case iIMUL:
@ -1076,12 +1076,12 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
use (DST, pIcode, this, pstate, cb); use (DST, pIcode, this, pstate, cb);
if (cb == 1) if (cb == 1)
{ {
pIcode.du.def |= duReg[rAX]; pIcode.du.def.addReg(rAX);
pIcode.du1.numRegsDef++; pIcode.du1.numRegsDef++;
} }
else else
{ {
pIcode.du.def |= (duReg[rAX] | duReg[rDX]); pIcode.du.def.addReg(rAX).addReg(rDX);
pIcode.du1.numRegsDef += 2; pIcode.du1.numRegsDef += 2;
} }
} }
@ -1093,15 +1093,15 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
cb = pIcode.ll()->testFlags(SRC_B) ? 1 : 2; cb = pIcode.ll()->testFlags(SRC_B) ? 1 : 2;
if (cb == 1) /* uint8_t */ if (cb == 1) /* uint8_t */
{ {
pIcode.du.def |= duReg[rAX]; pIcode.du.def.addReg(rAX);
pIcode.du1.numRegsDef++; pIcode.du1.numRegsDef++;
pIcode.du.use |= duReg[rAL]; pIcode.du.use.addReg(rAL);
} }
else /* uint16_t */ else /* uint16_t */
{ {
pIcode.du.def |= (duReg[rDX] | duReg[rAX]); pIcode.du.def.addReg(rDX).addReg(rAX);
pIcode.du1.numRegsDef += 2; pIcode.du1.numRegsDef += 2;
pIcode.du.use |= duReg[rAX]; pIcode.du.use.addReg(rAX);
} }
break; break;
@ -1121,7 +1121,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
break; break;
case iLDS: case iLES: case iLDS: case iLES:
pIcode.du.def |= duReg[(pIcode.ll()->getOpcode() == iLDS) ? rDS : rES]; pIcode.du.def.addReg(((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES));
pIcode.du1.numRegsDef++; pIcode.du1.numRegsDef++;
cb = 4; cb = 4;
case iMOV: case iMOV:
@ -1147,10 +1147,10 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
break; break;
case iLOOP: case iLOOPE: case iLOOPNE: case iLOOP: case iLOOPE: case iLOOPNE:
pIcode.du.def |= duReg[rCX]; pIcode.du.def.addReg(rCX);
pIcode.du1.numRegsDef++; pIcode.du1.numRegsDef++;
case iJCXZ: case iJCXZ:
pIcode.du.use |= duReg[rCX]; pIcode.du.use.addReg(rCX);
break; break;
case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS: case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS:
@ -1160,22 +1160,22 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
pIcode.du.addDefinedAndUsed(rSI); pIcode.du.addDefinedAndUsed(rSI);
pIcode.du.addDefinedAndUsed(rDI); pIcode.du.addDefinedAndUsed(rDI);
pIcode.du1.numRegsDef += 2; pIcode.du1.numRegsDef += 2;
pIcode.du.use |= duReg[rES] | duReg[sseg]; pIcode.du.use.addReg(rES).addReg(sseg);
break; break;
case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS: case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS:
pIcode.du.addDefinedAndUsed(rCX); pIcode.du.addDefinedAndUsed(rCX);
pIcode.du1.numRegsDef++; pIcode.du1.numRegsDef++;
case iSCAS: case iSTOS: case iINS: case iSCAS: case iSTOS: case iINS:
pIcode.du.def |= duReg[rDI]; pIcode.du.def.addReg(rDI);
pIcode.du1.numRegsDef++; pIcode.du1.numRegsDef++;
if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS) if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS)
{ {
pIcode.du.use |= duReg[rDI] | duReg[rES] | duReg[rDX]; pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX);
} }
else else
{ {
pIcode.du.use |= duReg[rDI] | duReg[rES] | duReg[(cb == 2)? rAX: rAL]; pIcode.du.use.addReg(rDI).addReg(rES).addReg((cb == 2)? rAX: rAL);
} }
break; break;

View File

@ -5,10 +5,10 @@
********************************************************************/ ********************************************************************/
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstdio>
#include <cstring>
#include <stdint.h>
#include "dcc.h" #include "dcc.h"
#include <stdio.h>
#include <malloc.h> /* For free() */
#include <string.h>
static int numInt; /* Number of intervals */ static int numInt; /* Number of intervals */
@ -66,16 +66,16 @@ BB *interval::firstOfInt ()
* node->inInterval. * node->inInterval.
* Note: nodes are added to the interval list in interval order (which * Note: nodes are added to the interval list in interval order (which
* topsorts the dominance relation). */ * topsorts the dominance relation). */
static void appendNodeInt (queue &pqH, BB *node, interval *pI) void interval::appendNodeInt(queue &pqH, BB *node)
{ {
queue::iterator pq; /* Pointer to current node of the list */ queue::iterator pq; /* Pointer to current node of the list */
/* Append node if it is not already in the interval list */ /* Append node if it is not already in the interval list */
pq = appendQueue (pI->nodes, node); pq = appendQueue (nodes, node);
/* Update currNode if necessary */ /* Update currNode if necessary */
if (pI->currNode == pI->nodes.end()) if (currNode == nodes.end())
pI->currNode = pq; currNode = pq;
/* Check header list for occurrence of node, if found, remove it /* Check header list for occurrence of node, if found, remove it
* and decrement number of out-edges from this interval. */ * and decrement number of out-edges from this interval. */
@ -84,12 +84,12 @@ 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 -= (uint8_t)(*found_iter)->inEdges.size() - 1; numOutEdges -= (uint8_t)(*found_iter)->inEdges.size() - 1;
pqH.erase(found_iter); pqH.erase(found_iter);
} }
} }
/* Update interval header information for this basic block */ /* Update interval header information for this basic block */
node->inInterval = pI; node->inInterval = this;
} }
@ -103,7 +103,6 @@ void derSeq_Entry::findIntervals (Function *c)
BB *h, /* Node being processed */ BB *h, /* Node being processed */
*header, /* Current interval's header node */ *header, /* Current interval's header node */
*succ; /* Successor basic block */ *succ; /* Successor basic block */
//int i; /* Counter */
queue H; /* Queue of possible header nodes */ queue H; /* Queue of possible header nodes */
boolT first = true; /* First pass through the loop */ boolT first = true; /* First pass through the loop */
@ -118,8 +117,11 @@ void derSeq_Entry::findIntervals (Function *c)
pI = new interval; pI = new interval;
pI->numInt = (uint8_t)numInt++; pI->numInt = (uint8_t)numInt++;
if (first) /* ^ to first interval */ if (first) /* ^ to first interval */
{
Ii = J = pI; Ii = J = pI;
appendNodeInt (H, header, pI); /* pI(header) = {header} */ m_intervals.push_back(pI);
}
pI->appendNodeInt (H, header); /* pI(header) = {header} */
/* Process all nodes in the current interval list */ /* Process all nodes in the current interval list */
while ((h = pI->firstOfInt()) != NULL) while ((h = pI->firstOfInt()) != NULL)
@ -134,7 +136,7 @@ void derSeq_Entry::findIntervals (Function *c)
{ {
succ->reachingInt = header; succ->reachingInt = header;
if (succ->inEdgeCount == 0) if (succ->inEdgeCount == 0)
appendNodeInt (H, succ, pI); pI->appendNodeInt (H, succ);
else if (! succ->beenOnH) /* out edge */ else if (! succ->beenOnH) /* out edge */
{ {
appendQueue (H, succ); appendQueue (H, succ);
@ -148,7 +150,7 @@ void derSeq_Entry::findIntervals (Function *c)
if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */ if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */
{ {
if (succ != header) if (succ != header)
appendNodeInt (H, succ, pI); pI->appendNodeInt (H, succ);
} }
else /* out edge */ else /* out edge */
pI->numOutEdges++; pI->numOutEdges++;
@ -161,6 +163,7 @@ void derSeq_Entry::findIntervals (Function *c)
/* Link interval I to list of intervals */ /* Link interval I to list of intervals */
if (! first) if (! first)
{ {
m_intervals.push_back(pI);
J->next = pI; J->next = pI;
J = pI; J = pI;
} }
@ -333,13 +336,6 @@ uint8_t Function::findDerivedSeq (derSeq &derivedGi)
return true; return true;
} }
/* Converts the irreducible graph G into an equivalent reducible one, by
* means of node splitting. */
static void nodeSplitting (std::list<BB *> &/*G*/)
{
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
}
/* Displays the derived sequence and intervals of the graph G */ /* Displays the derived sequence and intervals of the graph G */
void derSeq::display() void derSeq::display()
{ {
@ -369,13 +365,13 @@ derSeq * Function::checkReducibility()
stats.nOrder = 1; /* nOrder(cfg) = 1 */ stats.nOrder = 1; /* nOrder(cfg) = 1 */
der_seq = new derSeq; der_seq = new derSeq;
der_seq->resize(1); der_seq->resize(1);
der_seq->back().Gi = m_cfg.front(); der_seq->back().Gi = *m_actual_cfg.begin(); /*m_cfg.front()*/;
reducible = findDerivedSeq(*der_seq); reducible = findDerivedSeq(*der_seq);
if (! reducible) if (! reducible)
{ {
flg |= GRAPH_IRRED; flg |= GRAPH_IRRED;
nodeSplitting (m_cfg); m_actual_cfg.nodeSplitting();
} }
return der_seq; return der_seq;
} }

View File

@ -30,7 +30,7 @@
#define TABLESIZE 16 /* Number of entries added each expansion */ #define TABLESIZE 16 /* Number of entries added each expansion */
/* Probably has to be a power of 2 */ /* Probably has to be a power of 2 */
#define STRTABSIZE 256 /* Size string table is inc'd by */ #define STRTABSIZE 256 /* Size string table is inc'd by */
#define NIL ((uint16_t)-1)
using namespace std; using namespace std;
static char *pStrTab; /* Pointer to the current string table */ static char *pStrTab; /* Pointer to the current string table */
static int strTabNext; /* Next free index into pStrTab */ static int strTabNext; /* Next free index into pStrTab */

View File

@ -60,7 +60,8 @@ void Function::controlFlowAnalysis()
if (option.verbose) if (option.verbose)
{ {
printf("\nDepth first traversal - Proc %s\n", name.c_str()); printf("\nDepth first traversal - Proc %s\n", name.c_str());
m_cfg.front()->displayDfs(); (*m_actual_cfg.begin())->displayDfs();
//m_cfg.front()->displayDfs();
} }
/* Free storage occupied by this procedure */ /* Free storage occupied by this procedure */
@ -82,7 +83,7 @@ void udm(void)
/* 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 */
std::bitset<32> live_regs; LivenessSet live_regs;
Project::get()->pProcList.front().dataFlow (live_regs); Project::get()->pProcList.front().dataFlow (live_regs);
/* Control flow analysis - structuring algorithm */ /* Control flow analysis - structuring algorithm */
@ -98,7 +99,7 @@ void udm(void)
void Function::displayCFG() void Function::displayCFG()
{ {
printf("\nBasic Block List - Proc %s", name.c_str()); printf("\nBasic Block List - Proc %s", name.c_str());
for (BB *pBB : m_cfg) for (BB *pBB : /*m_cfg*/m_actual_cfg)
{ {
pBB->display(); pBB->display();
} }

View File

@ -3,4 +3,4 @@ cd bld
make -j5 make -j5
cd .. cd ..
./test_use_base.sh ./test_use_base.sh
./valgrind_tester ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/ ./valgrind_tester ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/