From c19231a1bddc0e8308b4733ac8b7448e88c5dc99 Mon Sep 17 00:00:00 2001 From: Artur K Date: Sun, 15 Jul 2012 16:52:59 +0200 Subject: [PATCH] extracted FunctionCfg as it's own class --- CMakeLists.txt | 7 +- base_regression.sh | 8 +- full_regression.sh | 2 +- include/BasicBlock.h | 30 +++--- include/Procedure.h | 34 +++++-- include/ast.h | 2 +- include/dcc.h | 4 +- include/disassem.h | 29 ++---- include/dosdcc.h | 9 +- include/graph.h | 18 ++-- include/icode.h | 56 ++++++++--- include/machine_x86.h | 2 +- include/perfhlib.h | 5 +- src/BasicBlock.cpp | 25 +++-- src/ast.cpp | 7 +- src/backend.cpp | 2 +- src/chklib.cpp | 12 +-- src/dataflow.cpp | 211 ++++++++++++++++++++---------------------- src/frontend.cpp | 3 +- src/graph.cpp | 16 ++-- src/hlicode.cpp | 30 ++++-- src/icode.cpp | 5 - src/locident.cpp | 4 +- src/parser.cpp | 32 +++---- src/reducible.cpp | 42 ++++----- src/symtab.cpp | 2 +- src/udm.cpp | 7 +- valgrind_base.sh | 2 +- 28 files changed, 315 insertions(+), 291 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36c412f..7bb19c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 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)") ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE) ADD_DEFINITIONS(/W4) @@ -14,7 +14,7 @@ ELSE() ENDIF() SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH}) - +include(cotire) FIND_PACKAGE(LLVM) FIND_PACKAGE(Boost) IF(dcc_build_tests) @@ -59,6 +59,7 @@ set(dcc_LIB_SOURCES src/idioms/shift_idioms.cpp src/idioms/xor_idioms.cpp src/locident.cpp + src/liveness_set.cpp src/parser.cpp src/perfhlib.cpp src/procs.cpp @@ -110,11 +111,11 @@ SOURCE_GROUP(Source FILES ${dcc_SOURCES}) SOURCE_GROUP(Headers FILES ${dcc_HEADERS}) ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS}) +cotire(dcc_lib) ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS}) ADD_DEPENDENCIES(dcc_original dcc_lib) TARGET_LINK_LIBRARIES(dcc_original dcc_lib disasm_s ${REQ_LLVM_LIBRARIES}) - if(dcc_build_tests) ADD_SUBDIRECTORY(src) endif() diff --git a/base_regression.sh b/base_regression.sh index 957b4c6..5065e25 100755 --- a/base_regression.sh +++ b/base_regression.sh @@ -1,6 +1,6 @@ #!/bin/bash -cd bld -make -j5 -cd .. +#cd bld +#make -j5 +#cd .. ./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/ diff --git a/full_regression.sh b/full_regression.sh index e64a873..d7e6324 100755 --- a/full_regression.sh +++ b/full_regression.sh @@ -1,3 +1,3 @@ #!/bin/bash ./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/ diff --git a/include/BasicBlock.h b/include/BasicBlock.h index 7be8cd0..ba6a6c3 100644 --- a/include/BasicBlock.h +++ b/include/BasicBlock.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "icode.h" #include "types.h" #include "graph.h" @@ -27,10 +27,9 @@ struct TYPEADR_TYPE TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v) {} }; - struct BB : public llvm::ilist_node { - + friend struct Function; private: BB(const BB&); BB() : nodeType(0),traversed(DFS_NONE), @@ -46,6 +45,7 @@ private: //friend class SymbolTableListTraits; typedef boost::iterator_range rCODE; rCODE instructions; + rCODE &my_range() {return instructions;} public: struct ValidFunctor @@ -77,29 +77,25 @@ public: interval *inInterval; /* Node's interval */ /* For derived sequence construction */ - interval *correspInt; /* Corresponding interval in - * derived graph Gi-1 */ - - /* For live register analysis - * LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) */ - std::bitset<32> liveUse; /* LiveUse(b) */ - std::bitset<32> def; /* Def(b) */ - std::bitset<32> liveIn; /* LiveIn(b) */ - std::bitset<32> liveOut; /* LiveOut(b) */ + interval *correspInt; //!< Corresponding interval in derived graph Gi-1 + // For live register analysis + // LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) + LivenessSet liveUse; /* LiveUse(b) */ + LivenessSet def; /* Def(b) */ + LivenessSet liveIn; /* LiveIn(b) */ + LivenessSet liveOut; /* LiveOut(b) */ /* For structuring analysis */ int dfsFirstNum; /* DFS #: first visit of node */ int dfsLastNum; /* DFS #: last visit of node */ - int immedDom; /* Immediate dominator (dfsLast - * index) */ + int immedDom; /* Immediate dominator (dfsLast index) */ int ifFollow; /* node that ends the if */ int loopType; /* Type of loop (if any) */ int latchNode; /* latching node of the loop */ size_t numBackEdges; /* # of back edges */ int loopHead; /* most nested loop head to which this node belongs (dfsLast) */ int loopFollow; /* node that follows the loop */ - int caseHead; /* most nested case to which this - node belongs (dfsLast) */ + int caseHead; /* most nested case to which this node belongs (dfsLast) */ int caseTail; /* tail node for the case */ int index; /* Index, used in several ways */ @@ -134,7 +130,7 @@ public: void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode); private: 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; Function *Parent; diff --git a/include/Procedure.h b/include/Procedure.h index ab99f26..fb196a0 100644 --- a/include/Procedure.h +++ b/include/Procedure.h @@ -86,7 +86,26 @@ struct JumpTable size_t entrySize() { return 2;} void pruneEntries(uint16_t cs); }; - +class FunctionCfg +{ + std::list m_listBB; /* Ptr. to BB list/CFG */ +public: + typedef std::list::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 { typedef llvm::iplist BasicBlockListType; @@ -109,6 +128,7 @@ public: /* Icodes and control flow graph */ CIcodeRec Icode; /* Object with ICODE records */ + FunctionCfg m_actual_cfg; std::list m_cfg; /* Ptr. to BB list/CFG */ std::vector m_dfsLast; std::list heldBBs; @@ -118,9 +138,9 @@ public: bool hasCase; /* Procedure has a case node */ /* For interprocedural live analysis */ - std::bitset<32> liveIn; /* Registers used before defined */ - std::bitset<32> liveOut; /* Registers that may be used in successors */ - bool liveAnal; /* Procedure has been analysed already */ + LivenessSet liveIn; /* Registers used before defined */ + LivenessSet liveOut; /* Registers that may be used in successors */ + 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), hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0) @@ -140,7 +160,7 @@ public: void writeProcComments(); void lowLevelAnalysis(); void bindIcodeOff(); - void dataFlow(std::bitset<32> &liveOut); + void dataFlow(LivenessSet &liveOut); void compressCFG(); void highLevelGen(); void structure(derSeq *derivedG); @@ -166,7 +186,7 @@ public: void displayStats(); void processHliCall(COND_EXPR *exp, iICODE picode); - void preprocessReturnDU(std::bitset<32> &_liveOut); + void preprocessReturnDU(LivenessSet &_liveOut); protected: void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table); bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate); @@ -190,7 +210,7 @@ protected: void findExps(); void genDU1(); void elimCondCodes(); - void liveRegAnalysis(std::bitset<32> &in_liveOut); + void liveRegAnalysis(LivenessSet &in_liveOut); void findIdioms(); void propLong(); void genLiveKtes(); diff --git a/include/ast.h b/include/ast.h index 52c7b60..40ef840 100644 --- a/include/ast.h +++ b/include/ast.h @@ -7,8 +7,8 @@ #pragma once #include #include +#include #include "Enums.h" -#include static const int operandSize=20; /* The following definitions and types define the Conditional Expression * attributed syntax tree, as defined by the following EBNF: diff --git a/include/dcc.h b/include/dcc.h index 698fa86..262f8c2 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -62,10 +62,10 @@ typedef struct { /* Command line option flags */ extern OPTION option; /* Command line options */ #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 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 */ diff --git a/include/disassem.h b/include/disassem.h index 5bcc7bc..d0755bf 100644 --- a/include/disassem.h +++ b/include/disassem.h @@ -1,9 +1,10 @@ -/**************************************************************************** - * dcc project disassembler header - * (C) Mike van Emmerik - ****************************************************************************/ +/* +*************************************************************************** + dcc project disassembler header + (C) Mike van Emmerik +*************************************************************************** +*/ #pragma once -#include #include #include #include "bundle.h" @@ -32,24 +33,6 @@ public: #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__ #define KEY_DOWN EXT+'B' #define KEY_LEFT EXT+'D' diff --git a/include/dosdcc.h b/include/dosdcc.h index f177938..b148883 100644 --- a/include/dosdcc.h +++ b/include/dosdcc.h @@ -1,8 +1,11 @@ -/*************************************************************************** +/* + +=************************************************************************** * File : dosdcc.h * Purpose : include file for files decompiled by dcc. * Copyright (c) Cristina Cifuentes - QUT - 1992 - **************************************************************************/ + ************************************************************************* +*/ /* Type definitions for intel 80x86 architecture */ typedef unsigned int uint16_t; /* 16 bits */ @@ -18,7 +21,7 @@ typedef struct { uint16_t lowBitWord : 1; uint16_t filler1 : 6; uint16_t highBitByte : 1; - /* high uint8_t */ + /* high uint8_t */ uint16_t lowBitByte : 1; uint16_t filler2 : 6; uint16_t highBitWord : 1; diff --git a/include/graph.h b/include/graph.h index 714b0ed..8923855 100644 --- a/include/graph.h +++ b/include/graph.h @@ -1,10 +1,13 @@ -/***************************************************************************** +/* + **************************************************************************** * CFG, BB and interval related definitions - * (C) Cristina Cifuentes - ****************************************************************************/ + * ( C ) Cristina Cifuentes + **************************************************************************** + */ #pragma once +#include #include -#include + struct Function; /* Types of basic block nodes */ /* Real basic blocks: type defined according to their out-edges */ @@ -55,6 +58,7 @@ enum eNodeHeaderType #define ELSE 1 /* else edge */ /* Basic Block (BB) flags */ + #define INVALID_BB 0x0001 /* BB is not valid any more */ #define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */ @@ -64,8 +68,8 @@ typedef std::list queue; struct interval { - uint8_t numInt; /* # of the interval */ - uint8_t numOutEdges; /* Number of out edges */ + uint8_t numInt; /* # of the interval */ + uint8_t numOutEdges; /* Number of out edges */ queue nodes; /* Nodes of the interval*/ queue::iterator currNode; /* Current node */ interval *next; /* Next interval */ @@ -76,6 +80,7 @@ struct interval currNode=nodes.end(); next=0; } + void appendNodeInt(queue &pqH, BB *node); }; @@ -83,6 +88,7 @@ struct interval struct derSeq_Entry { BB * Gi; /* Graph pointer */ + std::list m_intervals; interval * Ii; /* Interval list of Gi */ derSeq_Entry() : Gi(0),Ii(0) { diff --git a/include/icode.h b/include/icode.h index 1611f87..dd9bd4f 100644 --- a/include/icode.h +++ b/include/icode.h @@ -9,12 +9,9 @@ #include #include #include -#include #include -#include -#include #include -#include +#include #include "libdis.h" #include "Enums.h" #include "state.h" // State depends on INDEXBASE, but later need STATE @@ -32,7 +29,45 @@ typedef std::list::iterator iICODE; typedef std::list::reverse_iterator riICODE; typedef boost::iterator_range 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 */ /* Def/use of flags - low 4 bits represent flags */ @@ -350,14 +385,13 @@ public: use.reset(); lastDefRegi.reset(); } - std::bitset<32> def; // For Registers: position in bitset is reg index - std::bitset<32> 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 def; // For Registers: position in bitset is reg index + LivenessSet use; // For Registers: position in uint32_t is reg index + LivenessSet lastDefRegi;// Bit set if last def of this register in BB void addDefinedAndUsed(eReg r) { - def |= duReg[r]; - use |= duReg[r]; - + def.addReg(r); + use.addReg(r); } }; struct DU1 diff --git a/include/machine_x86.h b/include/machine_x86.h index 9b6e082..cddcc66 100644 --- a/include/machine_x86.h +++ b/include/machine_x86.h @@ -73,7 +73,7 @@ public: 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 bool isMemOff(eReg r); diff --git a/include/perfhlib.h b/include/perfhlib.h index 1613b4f..bbcfb98 100644 --- a/include/perfhlib.h +++ b/include/perfhlib.h @@ -3,10 +3,7 @@ hashing functions * (C) Mike van Emmerik */ - -//#define bool unsigned char -#define uint8_t unsigned char -#define uint16_t unsigned short +#include /* Prototypes */ void hashCleanup(void); /* Frees memory allocated by hashParams() */ diff --git a/src/BasicBlock.cpp b/src/BasicBlock.cpp index 7f62cd0..c5ebf38 100644 --- a/src/BasicBlock.cpp +++ b/src/BasicBlock.cpp @@ -36,7 +36,7 @@ BB *BB::Create(const rCODE &r,uint8_t _nodeType, Function *parent) //setInBB should automatically handle if our range is empty parent->Icode.SetInBB(pnewBB->instructions, pnewBB); parent->heldBBs.push_back(pnewBB); - parent->m_cfg.push_back(pnewBB); + parent->m_actual_cfg.push_back(pnewBB); pnewBB->Parent = parent; } @@ -127,13 +127,11 @@ void BB::displayDfs() pb.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 */ +/** Recursive procedure that writes the code for the given procedure, pointed + to by pBB. + \param indLevel indentation level - used for formatting. + \param numLoc: last # assigned to local variables +*/ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond) { latch = pProc->m_dfsLast[this->latchNode]; @@ -177,6 +175,7 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat case ENDLESS_TYPE: ostr << "\n"<back(); } cCode.appendCode(ostr.str()); stats.numHLIcode += 1; @@ -226,7 +225,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode, return; /* Check type of loop/node and process code */ - if ( loopType) /* there is a loop */ + if ( loopType ) /* there is a loop */ { assert(latch); if (this != latch) /* loop is over several bbs */ @@ -391,16 +390,16 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc) iICODE BB::begin() { - return instructions.begin();//range_start; + return instructions.begin(); } iICODE BB::end() const { - return instructions.end();//range_end + return instructions.end(); } ICODE &BB::back() { - return instructions.back();//*rbegin(); + return instructions.back(); } size_t BB::size() @@ -411,7 +410,7 @@ size_t BB::size() ICODE &BB::front() { - return instructions.front();//*begin(); + return instructions.front(); } riICODE BB::rbegin() diff --git a/src/ast.cpp b/src/ast.cpp index c64b9fa..f9effd7 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -43,15 +43,14 @@ void ICODE::setRegDU (eReg regi, operDu du_in) switch (du_in) { case eDEF: - du.def |= duReg[regi]; + du.def.addReg(regi); du1.numRegsDef++; break; case eUSE: - du.use |= duReg[regi]; + du.use.addReg(regi); break; case USE_DEF: - du.def |= duReg[regi]; - du.use |= duReg[regi]; + du.addDefinedAndUsed(regi); du1.numRegsDef++; break; case NONE: /* do nothing */ diff --git a/src/backend.cpp b/src/backend.cpp index 1d16978..6def061 100644 --- a/src/backend.cpp +++ b/src/backend.cpp @@ -266,7 +266,7 @@ void Function::codeGen (std::ostream &fs) } 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"); diff --git a/src/chklib.cpp b/src/chklib.cpp index 98cd95a..fc7b94d 100644 --- a/src/chklib.cpp +++ b/src/chklib.cpp @@ -337,8 +337,7 @@ void SetupLibCheck(void) PatLen, /* The length of the pattern to be hashed */ 256, /* The character set of the pattern (0-FF) */ 0, /* Minimum pattern character value */ - numVert); /* Specifies c, the sparseness of the graph. - See Czech, Havas and Majewski for details */ + numVert); /* Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details */ T1base = g_pattern_hasher.readT1(); T2base = g_pattern_hasher.readT2(); g = g_pattern_hasher.readG(); @@ -462,8 +461,7 @@ bool LibCheck(Function & pProc) //memmove(pat, &prog.Image[fileOffset], PATLEN); fixWildCards(pat); /* Fix wild cards in the copy */ h = g_pattern_hasher.hash(pat); /* Hash the found proc */ - /* We always have to compare keys, because the hash function will - always return a valid index */ + /* We always have to compare keys, because the hash function will always return a valid index */ if (memcmp(ht[h].htPat, pat, PATLEN) == 0) { /* We have a match. Save the name, if not already set */ @@ -494,13 +492,13 @@ bool LibCheck(Function & pProc) pProc.flg |= PROC_IS_FUNC; switch (pProc.retVal.type) { case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: - pProc.liveOut = duReg[rDX] | duReg[rAX]; + pProc.liveOut.setReg(rDX) |= duReg[rAX]; break; case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: - pProc.liveOut = duReg[rAX]; + pProc.liveOut.setReg(rAX); break; case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: - pProc.liveOut = duReg[rAL]; + pProc.liveOut.setReg(rAL); break; default: fprintf(stderr,"Unknown retval type %d in LibCheck\n",pProc.retVal.type); diff --git a/src/dataflow.cpp b/src/dataflow.cpp index f766cdd..9729c83 100644 --- a/src/dataflow.cpp +++ b/src/dataflow.cpp @@ -45,7 +45,6 @@ void ExpStack::init() expStk.clear(); } - /* Pushes the given expression onto the local stack (expStk). */ 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 */ void Function::elimCondCodes () { -// int i; + // int i; uint8_t use; /* Used flags bit vector */ uint8_t def; /* Defined flags bit vector */ @@ -125,19 +124,11 @@ void Function::elimCondCodes () //BB * pBB; /* Pointer to BBs in dfs last ordering */ riICODE useAt; /* Instruction that used flag */ riICODE defAt; /* Instruction that defined flag */ - //lhs=rhs=_expr=0; + //lhs=rhs=_expr=0; auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) ); for( BB * pBB : valid_reversed_bbs) { - -// 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) - // {} + //auto reversed_instructions = pBB->range() | reversed; for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++) { llIcode useAtOp = llIcode(useAt->ll()->getOpcode()); @@ -234,7 +225,6 @@ void Function::elimCondCodes () else if (defAt == pBB->rend()) { reportError(DEF_NOT_FOUND,useAtOp); - //fatalError (DEF_NOT_FOUND, Icode.getOpcode(useAt-1)); } } } @@ -250,7 +240,7 @@ void Function::elimCondCodes () void Function::genLiveKtes () { BB * pbb; - bitset<32> liveUse, def; + LivenessSet liveUse, def; 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 * iterative approach. * 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::assign; - BB * pbb=0; /* pointer to current basic block */ - Function * pcallee; /* invoked subroutine */ + //BB * pbb=0; /* pointer to current basic block */ + Function * pcallee; /* invoked subroutine */ //ICODE *ticode /* icode that invokes a subroutine */ ; - std::bitset<32> prevLiveOut, /* previous live out */ + LivenessSet prevLiveOut, /* previous live out */ prevLiveIn; /* previous live in */ 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 */ change = false; 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 */ prevLiveIn = pbb->liveIn; @@ -349,22 +338,22 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) ) pbb->liveOut = pcallee->liveOut; 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) { - case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: - ticode.du1.numRegsDef = 2; - break; - case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: - case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: - ticode.du1.numRegsDef = 1; - break; - default: - ticode.du1.numRegsDef = 0; - //fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type); + case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN: + ticode.du1.numRegsDef = 2; + break; + case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN: + case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN: + ticode.du1.numRegsDef = 1; + break; + default: + ticode.du1.numRegsDef = 0; + //fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type); } /*eos*/ /* Propagate def/use results to calling icode */ @@ -375,28 +364,28 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut) } /* 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 */ if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut)) change = true; } } - + BB *pbb = m_dfsLast.front(); /* Propagate liveIn(b) to procedure header */ - if (pbb->liveIn != 0) /* uses registers */ + if (pbb->liveIn.any()) /* uses registers */ liveIn = pbb->liveIn; /* Remove any references to register variables */ if (flg & SI_REGVAR) { - liveIn &= maskDuReg[rSI]; - pbb->liveIn &= maskDuReg[rSI]; + liveIn.set(rSI,0); + pbb->liveIn.set(rSI,0); } if (flg & DI_REGVAR) { - liveIn &= maskDuReg[rDI]; - pbb->liveIn &= maskDuReg[rDI]; + liveIn.set(rDI,0); + 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 */ 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 */ { /* Check if last definition of this register */ if ((liveOut & duReg[regi]).any()) - start_at->du.lastDefRegi |= duReg[regi]; + start_at->du.lastDefRegi.addReg(regi); } 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 * next basic block (unoptimized code) or somewhere else * 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) && - (picode->hl()->call.proc->flg & PROC_IS_FUNC)) + if ((picode.hl()->opcode == HLI_CALL) && + (picode.hl()->call.proc->flg & PROC_IS_FUNC)) { BB *tbb = this->edges[0].BBptr; 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 ((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 ((iter->du.def & duReg[regi]).any()) break; @@ -468,8 +457,8 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode) /* if not used in this basic block, check if the * register is live out, if so, make it the last * definition of this register */ - if ( picode->du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any()) - picode->du.lastDefRegi |= duReg[regi]; + if ( picode.du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any()) + picode.du.lastDefRegi.addReg(regi); } } @@ -502,7 +491,7 @@ void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode) } } 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())) continue; - ProcessUseDefForFunc(regi, defRegIdx,picode.base()); + ProcessUseDefForFunc(regi, defRegIdx,*picode); RemoveUnusedDefs(regi, defRegIdx, picode.base()); defRegIdx++; @@ -734,47 +723,47 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode HLTYPE &t_hl(*ticode->hl()); switch (t_hl.opcode) { - case HLI_ASSIGN: - if(isLong) - { - forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx, - p_hl.asgn.rhs, picode,ticode, - &numHlIcodes); - } - else - this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes); - break; + case HLI_ASSIGN: + if(isLong) + { + forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx, + p_hl.asgn.rhs, picode,ticode, + &numHlIcodes); + } + else + this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes); + break; - case HLI_JCOND: case HLI_PUSH: case HLI_RET: - if(isLong) - { - res = COND_EXPR::insertSubTreeLongReg ( - p_hl.asgn.rhs, - &t_hl.exp.v, - p_hl.asgn.lhs->expr.ident.idNode.longIdx); - } - else - { - res = COND_EXPR::insertSubTreeReg ( - t_hl.exp.v, - p_hl.asgn.rhs, - id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi, + case HLI_JCOND: case HLI_PUSH: case HLI_RET: + if(isLong) + { + res = COND_EXPR::insertSubTreeLongReg ( + p_hl.asgn.rhs, + &t_hl.exp.v, + p_hl.asgn.lhs->expr.ident.idNode.longIdx); + } + else + { + res = COND_EXPR::insertSubTreeReg ( + t_hl.exp.v, + p_hl.asgn.rhs, + id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi, this); - } - if (res) - { + } + if (res) + { + picode->invalidate(); + numHlIcodes--; + } + break; + + case HLI_CALL: /* register arguments */ + newRegArg ( picode, ticode); picode->invalidate(); numHlIcodes--; - } - break; - - case HLI_CALL: /* register arguments */ - newRegArg ( picode, ticode); - picode->invalidate(); - numHlIcodes--; - break; - default: - fprintf(stderr,"unhandled LOCAL_ID::processTargetIcode opcode %d\n",t_hl.opcode); + break; + default: + fprintf(stderr,"unhandled LOCAL_ID::processTargetIcode opcode %d\n",t_hl.opcode); } } @@ -857,8 +846,6 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter()); 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()); numHlIcodes++; if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */ @@ -910,7 +897,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, locals.id_arr[_icHl.expr()->expr.ident.idNode.regiIdx].id.regi, - &locals); + &locals); if (res) { picode->invalidate(); @@ -1060,7 +1047,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc) res = COND_EXPR::insertSubTreeLongReg (_exp, &ticode->hl()->exp.v, locals.newLongReg ( _retVal->type, _retVal->id.longId.h, - _retVal->id.longId.l, picode.base())); + _retVal->id.longId.l, picode.base())); if (res) /* was substituted */ { picode->invalidate(); @@ -1125,11 +1112,11 @@ void Function::findExps() g_exp_stk.init(); /* Traverse tree in dfsLast order */ -// for (i = 0; i < numBBs; i++) + // for (i = 0; i < numBBs; i++) for(BB *pbb : m_dfsLast) { /* Process one BB */ -// pbb = m_dfsLast[i]; + // pbb = m_dfsLast[i]; if (not pbb->valid()) continue; 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()) { -// int idx; + // int idx; bool isAx, isBx, isCx, isDx; flg |= PROC_IS_FUNC; - isAx = _liveOut.test(rAX - rAX); - isBx = _liveOut.test(rBX - rAX); - isCx = _liveOut.test(rCX - rAX); - isDx = _liveOut.test(rDX - rAX); - bool isAL = !isAx && _liveOut.test(rAL - rAX); - bool isAH = !isAx && _liveOut.test(rAH - rAX); - bool isBL = !isBx && _liveOut.test(rBL - rAX); - bool isBH = !isBx && _liveOut.test(rBH - rAX); - bool isCL = !isCx && _liveOut.test(rCL - rAX); - bool isCH = !isCx && _liveOut.test(rCH - rAX); - bool isDL = !isDx && _liveOut.test(rDL - rAX); - bool isDH = !isDx && _liveOut.test(rDH - rAX); + isAx = _liveOut.testReg(rAX); + isBx = _liveOut.testReg(rBX); + isCx = _liveOut.testReg(rCX); + isDx = _liveOut.testReg(rDX); + bool isAL = !isAx && _liveOut.testReg(rAL); + bool isAH = !isAx && _liveOut.testReg(rAH); + bool isBL = !isBx && _liveOut.testReg(rBL); + bool isBH = !isBx && _liveOut.testReg(rBH); + bool isCL = !isCx && _liveOut.testReg(rCL); + bool isCH = !isCx && _liveOut.testReg(rCH); + bool isDL = !isDx && _liveOut.testReg(rDL); + bool isDH = !isDx && _liveOut.testReg(rDH); if(isAL && isAH) { isAx = true; @@ -1217,17 +1204,17 @@ void Function::preprocessReturnDU(std::bitset<32> &_liveOut) } } } -/** Invokes procedures related with data flow analysis. Works on a procedure - * at a time basis. - * Note: indirect recursion in liveRegAnalysis is possible. */ -void Function::dataFlow(std::bitset<32> &_liveOut) +/** Invokes procedures related with data flow analysis. + * Works on a procedure at a time basis. + \note indirect recursion in liveRegAnalysis is possible. */ +void Function::dataFlow(LivenessSet &_liveOut) { /* Remove references to register variables */ if (flg & SI_REGVAR) - _liveOut &= maskDuReg[rSI]; + _liveOut.set(rSI,0); if (flg & DI_REGVAR) - _liveOut &= maskDuReg[rDI]; + _liveOut.set(rDI,0); /* Function - return value register(s) */ preprocessReturnDU(_liveOut); diff --git a/src/frontend.cpp b/src/frontend.cpp index e9f1866..5c86a10 100644 --- a/src/frontend.cpp +++ b/src/frontend.cpp @@ -3,10 +3,11 @@ * Loads a program into simulated main memory and builds the procedure list. * (C) Cristina Cifuentes ****************************************************************************/ -#define __STDC_FORMAT_MACROS + #include "dcc.h" #include "disassem.h" #include +#include #include #include #include diff --git a/src/graph.cpp b/src/graph.cpp index b0dc454..a47791a 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -35,7 +35,7 @@ void Function::createCFG() * 5) Repeated string instructions * 6) End of procedure */ - int i; + BB * psBB; BB * pBB; iICODE pIcode = Icode.begin(); @@ -209,7 +209,7 @@ void Function::compressCFG() /* First pass over BB list removes redundant jumps of the form * (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)) continue; @@ -231,18 +231,17 @@ void Function::compressCFG() /* Next is a depth-first traversal merging any FALL_NODE or * ONE_BRANCH that fall through to a node with that as their only * in-edge. */ - m_cfg.front()->mergeFallThrough(Icode); + m_actual_cfg.front()->mergeFallThrough(Icode); /* Remove redundant BBs created by the above compressions * and allocate in-edge arrays as required. */ stats.numBBaft = stats.numBBbef; - - for(auto iter=m_cfg.begin(); iter!=m_cfg.end(); ++iter) + bool entry_node=true; + for(BB *pBB : m_actual_cfg) { - BB * pBB = *iter; 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; else { @@ -254,6 +253,7 @@ void Function::compressCFG() { pBB->inEdgeCount = pBB->inEdges.size(); } + entry_node=false; } /* Allocate storage for dfsLast[] array */ @@ -262,7 +262,7 @@ void Function::compressCFG() /* Now do a dfs numbering traversal and fill in the inEdges[] array */ last = numBBs - 1; - m_cfg.front()->dfsNumbering(m_dfsLast, &first, &last); + m_actual_cfg.front()->dfsNumbering(m_dfsLast, &first, &last); } diff --git a/src/hlicode.cpp b/src/hlicode.cpp index 42abb96..1c1fa90 100644 --- a/src/hlicode.cpp +++ b/src/hlicode.cpp @@ -10,18 +10,28 @@ #include #include "dcc.h" using namespace std; -#define ICODE_DELTA 25 + /* Masks off bits set by duReg[] */ -std::bitset<32> maskDuReg[] = { 0x00, - 0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */ - 0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F, - 0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */ - 0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */ - 0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF, - 0xEFFFFF, /* tmp reg */ - 0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */ - 0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 }; +LivenessSet maskDuReg[] = { 0x00, + /* uint16_t regs */ + 0xFEEFFE, //rAX + 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 */ + 0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF, + 0xEFFFFF, /* tmp reg */ + 0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */ + 0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 }; static char buf[lineSize]; /* Line buffer for hl icode output */ diff --git a/src/icode.cpp b/src/icode.cpp index d9c0574..97978ce 100644 --- a/src/icode.cpp +++ b/src/icode.cpp @@ -2,15 +2,12 @@ // (C) 1997 Mike Van Emmerik #include -#include -#include #include "dcc.h" #include "types.h" // Common types like uint8_t, etc #include "ast.h" // Some icode types depend on these #include "icode.h" -#define ICODE_DELTA 25 // Amount to allocate for new chunk ICODE::TypeFilter ICODE::select_high_level; ICODE::TypeAndValidFilter ICODE::select_valid_high_level; @@ -31,9 +28,7 @@ ICODE * CIcodeRec::addIcode(ICODE *pIcode) void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB) { for(ICODE &ic : rang) - { ic.setParent(pnewBB); - } } /* labelSrchRepl - Searches the icodes for instruction with label = target, and diff --git a/src/locident.cpp b/src/locident.cpp index 210d1dc..ad815dd 100644 --- a/src/locident.cpp +++ b/src/locident.cpp @@ -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) { - name[0]=0; macro[0]=0; memset(&id,0,sizeof(id)); } ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false) { - name[0]=0; macro[0]=0; memset(&id,0,sizeof(id)); loc=f; @@ -273,7 +271,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL) * number in an expression record. */ 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; LLInst &p_ll(*pIcode->ll()); if (f == LOW_FIRST) diff --git a/src/parser.cpp b/src/parser.cpp index 49fc08c..4a1be24 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2,7 +2,7 @@ * dcc project procedure list builder * (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann ****************************************************************************/ -#define __STDC_FORMAT_MACROS + #include #include #include /* 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 */ -std::bitset<32> duReg[] = { 0x00, +LivenessSet duReg[] = { 0x00, //AH AL . . AX, BH 0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */ 0x10, 0x20, 0x40, 0x80, @@ -1066,7 +1066,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate) case iDIV: case iIDIV: use(SRC, pIcode, this, pstate, cb); if (cb == 1) - pIcode.du.use |= duReg[rTMP]; + pIcode.du.use.addReg(rTMP); break; case iMUL: case iIMUL: @@ -1076,12 +1076,12 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate) use (DST, pIcode, this, pstate, cb); if (cb == 1) { - pIcode.du.def |= duReg[rAX]; + pIcode.du.def.addReg(rAX); pIcode.du1.numRegsDef++; } else { - pIcode.du.def |= (duReg[rAX] | duReg[rDX]); + pIcode.du.def.addReg(rAX).addReg(rDX); pIcode.du1.numRegsDef += 2; } } @@ -1093,15 +1093,15 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate) cb = pIcode.ll()->testFlags(SRC_B) ? 1 : 2; if (cb == 1) /* uint8_t */ { - pIcode.du.def |= duReg[rAX]; + pIcode.du.def.addReg(rAX); pIcode.du1.numRegsDef++; - pIcode.du.use |= duReg[rAL]; + pIcode.du.use.addReg(rAL); } else /* uint16_t */ { - pIcode.du.def |= (duReg[rDX] | duReg[rAX]); + pIcode.du.def.addReg(rDX).addReg(rAX); pIcode.du1.numRegsDef += 2; - pIcode.du.use |= duReg[rAX]; + pIcode.du.use.addReg(rAX); } break; @@ -1121,7 +1121,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate) break; 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++; cb = 4; case iMOV: @@ -1147,10 +1147,10 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate) break; case iLOOP: case iLOOPE: case iLOOPNE: - pIcode.du.def |= duReg[rCX]; + pIcode.du.def.addReg(rCX); pIcode.du1.numRegsDef++; case iJCXZ: - pIcode.du.use |= duReg[rCX]; + pIcode.du.use.addReg(rCX); break; 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(rDI); pIcode.du1.numRegsDef += 2; - pIcode.du.use |= duReg[rES] | duReg[sseg]; + pIcode.du.use.addReg(rES).addReg(sseg); break; case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS: pIcode.du.addDefinedAndUsed(rCX); pIcode.du1.numRegsDef++; case iSCAS: case iSTOS: case iINS: - pIcode.du.def |= duReg[rDI]; + pIcode.du.def.addReg(rDI); pIcode.du1.numRegsDef++; 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 { - 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; diff --git a/src/reducible.cpp b/src/reducible.cpp index 84b5ea8..2e2454c 100644 --- a/src/reducible.cpp +++ b/src/reducible.cpp @@ -5,10 +5,10 @@ ********************************************************************/ #include #include +#include +#include +#include #include "dcc.h" -#include -#include /* For free() */ -#include static int numInt; /* Number of intervals */ @@ -66,16 +66,16 @@ BB *interval::firstOfInt () * node->inInterval. * Note: nodes are added to the interval list in interval order (which * 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 */ /* Append node if it is not already in the interval list */ - pq = appendQueue (pI->nodes, node); + pq = appendQueue (nodes, node); /* Update currNode if necessary */ - if (pI->currNode == pI->nodes.end()) - pI->currNode = pq; + if (currNode == nodes.end()) + currNode = pq; /* Check header list for occurrence of node, if found, remove it * 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); 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); } } /* Update interval header information for this basic block */ - node->inInterval = pI; + node->inInterval = this; } @@ -99,11 +99,10 @@ static void appendNodeInt (queue &pqH, BB *node, interval *pI) void derSeq_Entry::findIntervals (Function *c) { interval *pI, /* Interval being processed */ - *J; /* ^ last interval in derivedGi->Ii */ + *J; /* ^ last interval in derivedGi->Ii */ BB *h, /* Node being processed */ *header, /* Current interval's header node */ *succ; /* Successor basic block */ - //int i; /* Counter */ queue H; /* Queue of possible header nodes */ boolT first = true; /* First pass through the loop */ @@ -118,8 +117,11 @@ void derSeq_Entry::findIntervals (Function *c) pI = new interval; pI->numInt = (uint8_t)numInt++; if (first) /* ^ to first interval */ + { 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 */ while ((h = pI->firstOfInt()) != NULL) @@ -134,7 +136,7 @@ void derSeq_Entry::findIntervals (Function *c) { succ->reachingInt = header; if (succ->inEdgeCount == 0) - appendNodeInt (H, succ, pI); + pI->appendNodeInt (H, succ); else if (! succ->beenOnH) /* out edge */ { appendQueue (H, succ); @@ -148,7 +150,7 @@ void derSeq_Entry::findIntervals (Function *c) if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */ { if (succ != header) - appendNodeInt (H, succ, pI); + pI->appendNodeInt (H, succ); } else /* out edge */ pI->numOutEdges++; @@ -161,6 +163,7 @@ void derSeq_Entry::findIntervals (Function *c) /* Link interval I to list of intervals */ if (! first) { + m_intervals.push_back(pI); J->next = pI; J = pI; } @@ -333,13 +336,6 @@ uint8_t Function::findDerivedSeq (derSeq &derivedGi) return true; } -/* Converts the irreducible graph G into an equivalent reducible one, by - * means of node splitting. */ -static void nodeSplitting (std::list &/*G*/) -{ - fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n"); -} - /* Displays the derived sequence and intervals of the graph G */ void derSeq::display() { @@ -369,13 +365,13 @@ derSeq * Function::checkReducibility() stats.nOrder = 1; /* nOrder(cfg) = 1 */ der_seq = new derSeq; 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); if (! reducible) { flg |= GRAPH_IRRED; - nodeSplitting (m_cfg); + m_actual_cfg.nodeSplitting(); } return der_seq; } diff --git a/src/symtab.cpp b/src/symtab.cpp index 4cdd95c..22018cf 100644 --- a/src/symtab.cpp +++ b/src/symtab.cpp @@ -30,7 +30,7 @@ #define TABLESIZE 16 /* Number of entries added each expansion */ /* Probably has to be a power of 2 */ #define STRTABSIZE 256 /* Size string table is inc'd by */ -#define NIL ((uint16_t)-1) + using namespace std; static char *pStrTab; /* Pointer to the current string table */ static int strTabNext; /* Next free index into pStrTab */ diff --git a/src/udm.cpp b/src/udm.cpp index a4395be..03c461d 100644 --- a/src/udm.cpp +++ b/src/udm.cpp @@ -60,7 +60,8 @@ void Function::controlFlowAnalysis() if (option.verbose) { 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 */ @@ -82,7 +83,7 @@ void udm(void) /* Data flow analysis - eliminate condition codes, extraneous registers * and intermediate instructions. Find expressions by forward * substitution algorithm */ - std::bitset<32> live_regs; + LivenessSet live_regs; Project::get()->pProcList.front().dataFlow (live_regs); /* Control flow analysis - structuring algorithm */ @@ -98,7 +99,7 @@ void udm(void) void Function::displayCFG() { printf("\nBasic Block List - Proc %s", name.c_str()); - for (BB *pBB : m_cfg) + for (BB *pBB : /*m_cfg*/m_actual_cfg) { pBB->display(); } diff --git a/valgrind_base.sh b/valgrind_base.sh index a3afc08..a21ce2e 100755 --- a/valgrind_base.sh +++ b/valgrind_base.sh @@ -3,4 +3,4 @@ cd bld make -j5 cd .. ./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/