Browse Source

extracted FunctionCfg as it's own class

Artur K 11 years ago
parent
commit
c19231a1bd

+ 4 - 3
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()

+ 4 - 4
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/

+ 1 - 1
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/

+ 13 - 17
include/BasicBlock.h

@@ -5,7 +5,7 @@
 #include <string>
 #include <llvm/ADT/ilist.h>
 #include <llvm/ADT/ilist_node.h>
-#include <boost/range.hpp>
+#include <boost/range/iterator_range.hpp>
 #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<BB>
 {
-
+    friend struct Function;
 private:
     BB(const BB&);
     BB() : nodeType(0),traversed(DFS_NONE),
@@ -46,6 +45,7 @@ private:
     //friend class SymbolTableListTraits<BB, Function>;
     typedef boost::iterator_range<iICODE> 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;
 

+ 27 - 7
include/Procedure.h

@@ -86,7 +86,26 @@ struct JumpTable
     size_t entrySize() { return 2;}
     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>
 {
     typedef llvm::iplist<BB> BasicBlockListType;
@@ -109,6 +128,7 @@ public:
 
         /* Icodes and control flow graph */
     CIcodeRec	 Icode;     /* Object with ICODE records                 */
+    FunctionCfg     m_actual_cfg;
     std::list<BB*> m_cfg;      /* Ptr. to BB list/CFG                  	 */
     std::vector<BB*> m_dfsLast;
     std::list<BB*> 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();

+ 1 - 1
include/ast.h

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

+ 2 - 2
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 */
 

+ 6 - 23
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 <sstream>
 #include <fstream>
 #include <vector>
 #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'

+ 6 - 3
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;

+ 12 - 6
include/graph.h

@@ -1,10 +1,13 @@
-/*****************************************************************************
+/*
+ ****************************************************************************
  *      CFG, BB and interval related definitions
- * (C) Cristina Cifuentes
- ****************************************************************************/
+ * ( C ) Cristina Cifuentes
+ ****************************************************************************
+ */
 #pragma once
+#include <stdint.h>
 #include <list>
-#include <vector>
+
 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<BB *> 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<interval *> m_intervals;
     interval *          Ii;        /* Interval list of Gi  */
     derSeq_Entry() : Gi(0),Ii(0)
     {

+ 45 - 11
include/icode.h

@@ -9,12 +9,9 @@
 #include <bitset>
 #include <llvm/ADT/ilist.h>
 #include <llvm/ADT/ilist_node.h>
-#include <llvm/CodeGen/MachineInstr.h>
 #include <llvm/MC/MCInst.h>
-#include <llvm/MC/MCAsmInfo.h>
-#include <llvm/Value.h>
 #include <llvm/Instruction.h>
-#include <boost/range.hpp>
+#include <boost/range/iterator_range.hpp>
 #include "libdis.h"
 #include "Enums.h"
 #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 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 */
 
 /* 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

+ 1 - 1
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);

+ 1 - 4
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 <stdint.h>
 
 /* Prototypes */
 void hashCleanup(void);         /* Frees memory allocated by hashParams() */

+ 12 - 13
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"<<indentStr(indLevel)<<"for (;;) {\n";
+            picode = &latch->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()

+ 3 - 4
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 */

+ 1 - 1
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");

+ 5 - 7
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);

+ 99 - 112
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<HIGH_LEVEL>());
     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);

+ 2 - 1
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 <stdio.h>
+#include <stdint.h>
 #include <inttypes.h>
 #include <stdlib.h>
 #include <string.h>

+ 8 - 8
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);
 }
 
 

+ 20 - 10
src/hlicode.cpp

@@ -10,18 +10,28 @@
 #include <sstream>
 #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 */
 

+ 0 - 5
src/icode.cpp

@@ -2,15 +2,12 @@
 // (C) 1997 Mike Van Emmerik
 
 #include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
 
 #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<HIGH_LEVEL> ICODE::select_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)
 {
     for(ICODE &ic : rang)
-    {
         ic.setParent(pnewBB);
-    }
 }
 
 /* labelSrchRepl - Searches the icodes for instruction with label = target, and

+ 1 - 3
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)

+ 16 - 16
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 <inttypes.h>
 #include <string.h>
 #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 */
-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;
 

+ 19 - 23
src/reducible.cpp

@@ -5,10 +5,10 @@
  ********************************************************************/
 #include <algorithm>
 #include <cassert>
+#include <cstdio>
+#include <cstring>
+#include <stdint.h>
 #include "dcc.h"
-#include <stdio.h>
-#include <malloc.h>		/* For free() */
-#include <string.h>
 
 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<BB *> &/*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;
 }

+ 1 - 1
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 */

+ 4 - 3
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();
     }

+ 1 - 1
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/