extracted FunctionCfg as it's own class
This commit is contained in:
parent
5087a051b5
commit
c19231a1bd
@ -3,7 +3,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
|||||||
|
|
||||||
OPTION(dcc_build_tests "Enable unit tests." OFF)
|
OPTION(dcc_build_tests "Enable unit tests." OFF)
|
||||||
|
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS)
|
||||||
IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
IF(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS -D__UNIX__ -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||||
ADD_DEFINITIONS(/W4)
|
ADD_DEFINITIONS(/W4)
|
||||||
@ -14,7 +14,7 @@ ELSE()
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
|
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeScripts;${CMAKE_MODULE_PATH})
|
||||||
|
include(cotire)
|
||||||
FIND_PACKAGE(LLVM)
|
FIND_PACKAGE(LLVM)
|
||||||
FIND_PACKAGE(Boost)
|
FIND_PACKAGE(Boost)
|
||||||
IF(dcc_build_tests)
|
IF(dcc_build_tests)
|
||||||
@ -59,6 +59,7 @@ set(dcc_LIB_SOURCES
|
|||||||
src/idioms/shift_idioms.cpp
|
src/idioms/shift_idioms.cpp
|
||||||
src/idioms/xor_idioms.cpp
|
src/idioms/xor_idioms.cpp
|
||||||
src/locident.cpp
|
src/locident.cpp
|
||||||
|
src/liveness_set.cpp
|
||||||
src/parser.cpp
|
src/parser.cpp
|
||||||
src/perfhlib.cpp
|
src/perfhlib.cpp
|
||||||
src/procs.cpp
|
src/procs.cpp
|
||||||
@ -110,11 +111,11 @@ SOURCE_GROUP(Source FILES ${dcc_SOURCES})
|
|||||||
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
SOURCE_GROUP(Headers FILES ${dcc_HEADERS})
|
||||||
|
|
||||||
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
|
ADD_LIBRARY(dcc_lib STATIC ${dcc_LIB_SOURCES} ${dcc_HEADERS})
|
||||||
|
cotire(dcc_lib)
|
||||||
|
|
||||||
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
ADD_EXECUTABLE(dcc_original ${dcc_SOURCES} ${dcc_HEADERS})
|
||||||
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
ADD_DEPENDENCIES(dcc_original dcc_lib)
|
||||||
TARGET_LINK_LIBRARIES(dcc_original dcc_lib disasm_s ${REQ_LLVM_LIBRARIES})
|
TARGET_LINK_LIBRARIES(dcc_original dcc_lib disasm_s ${REQ_LLVM_LIBRARIES})
|
||||||
|
|
||||||
if(dcc_build_tests)
|
if(dcc_build_tests)
|
||||||
ADD_SUBDIRECTORY(src)
|
ADD_SUBDIRECTORY(src)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cd bld
|
#cd bld
|
||||||
make -j5
|
#make -j5
|
||||||
cd ..
|
#cd ..
|
||||||
./test_use_base.sh
|
./test_use_base.sh
|
||||||
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
./test_use_all.sh
|
./test_use_all.sh
|
||||||
./regression_tester.rb ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
./regression_tester.rb ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <llvm/ADT/ilist.h>
|
#include <llvm/ADT/ilist.h>
|
||||||
#include <llvm/ADT/ilist_node.h>
|
#include <llvm/ADT/ilist_node.h>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
@ -27,10 +27,9 @@ struct TYPEADR_TYPE
|
|||||||
TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v)
|
TYPEADR_TYPE(interval *v) : ip(0),BBptr(nullptr),intPtr(v)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BB : public llvm::ilist_node<BB>
|
struct BB : public llvm::ilist_node<BB>
|
||||||
{
|
{
|
||||||
|
friend struct Function;
|
||||||
private:
|
private:
|
||||||
BB(const BB&);
|
BB(const BB&);
|
||||||
BB() : nodeType(0),traversed(DFS_NONE),
|
BB() : nodeType(0),traversed(DFS_NONE),
|
||||||
@ -46,6 +45,7 @@ private:
|
|||||||
//friend class SymbolTableListTraits<BB, Function>;
|
//friend class SymbolTableListTraits<BB, Function>;
|
||||||
typedef boost::iterator_range<iICODE> rCODE;
|
typedef boost::iterator_range<iICODE> rCODE;
|
||||||
rCODE instructions;
|
rCODE instructions;
|
||||||
|
rCODE &my_range() {return instructions;}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct ValidFunctor
|
struct ValidFunctor
|
||||||
@ -77,29 +77,25 @@ public:
|
|||||||
interval *inInterval; /* Node's interval */
|
interval *inInterval; /* Node's interval */
|
||||||
|
|
||||||
/* For derived sequence construction */
|
/* For derived sequence construction */
|
||||||
interval *correspInt; /* Corresponding interval in
|
interval *correspInt; //!< Corresponding interval in derived graph Gi-1
|
||||||
* derived graph Gi-1 */
|
// For live register analysis
|
||||||
|
// LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b))
|
||||||
/* For live register analysis
|
LivenessSet liveUse; /* LiveUse(b) */
|
||||||
* LiveIn(b) = LiveUse(b) U (LiveOut(b) - Def(b)) */
|
LivenessSet def; /* Def(b) */
|
||||||
std::bitset<32> liveUse; /* LiveUse(b) */
|
LivenessSet liveIn; /* LiveIn(b) */
|
||||||
std::bitset<32> def; /* Def(b) */
|
LivenessSet liveOut; /* LiveOut(b) */
|
||||||
std::bitset<32> liveIn; /* LiveIn(b) */
|
|
||||||
std::bitset<32> liveOut; /* LiveOut(b) */
|
|
||||||
|
|
||||||
/* For structuring analysis */
|
/* For structuring analysis */
|
||||||
int dfsFirstNum; /* DFS #: first visit of node */
|
int dfsFirstNum; /* DFS #: first visit of node */
|
||||||
int dfsLastNum; /* DFS #: last visit of node */
|
int dfsLastNum; /* DFS #: last visit of node */
|
||||||
int immedDom; /* Immediate dominator (dfsLast
|
int immedDom; /* Immediate dominator (dfsLast index) */
|
||||||
* index) */
|
|
||||||
int ifFollow; /* node that ends the if */
|
int ifFollow; /* node that ends the if */
|
||||||
int loopType; /* Type of loop (if any) */
|
int loopType; /* Type of loop (if any) */
|
||||||
int latchNode; /* latching node of the loop */
|
int latchNode; /* latching node of the loop */
|
||||||
size_t numBackEdges; /* # of back edges */
|
size_t numBackEdges; /* # of back edges */
|
||||||
int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
|
int loopHead; /* most nested loop head to which this node belongs (dfsLast) */
|
||||||
int loopFollow; /* node that follows the loop */
|
int loopFollow; /* node that follows the loop */
|
||||||
int caseHead; /* most nested case to which this
|
int caseHead; /* most nested case to which this node belongs (dfsLast) */
|
||||||
node belongs (dfsLast) */
|
|
||||||
int caseTail; /* tail node for the case */
|
int caseTail; /* tail node for the case */
|
||||||
|
|
||||||
int index; /* Index, used in several ways */
|
int index; /* Index, used in several ways */
|
||||||
@ -134,7 +130,7 @@ public:
|
|||||||
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
|
void RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode);
|
||||||
private:
|
private:
|
||||||
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);
|
bool FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at);
|
||||||
void ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode);
|
void ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode);
|
||||||
bool isEndOfPath(int latch_node_idx) const;
|
bool isEndOfPath(int latch_node_idx) const;
|
||||||
Function *Parent;
|
Function *Parent;
|
||||||
|
|
||||||
|
|||||||
@ -86,7 +86,26 @@ struct JumpTable
|
|||||||
size_t entrySize() { return 2;}
|
size_t entrySize() { return 2;}
|
||||||
void pruneEntries(uint16_t cs);
|
void pruneEntries(uint16_t cs);
|
||||||
};
|
};
|
||||||
|
class FunctionCfg
|
||||||
|
{
|
||||||
|
std::list<BB*> m_listBB; /* Ptr. to BB list/CFG */
|
||||||
|
public:
|
||||||
|
typedef std::list<BB*>::iterator iterator;
|
||||||
|
iterator begin() {
|
||||||
|
return m_listBB.begin();
|
||||||
|
}
|
||||||
|
iterator end() {
|
||||||
|
return m_listBB.end();
|
||||||
|
}
|
||||||
|
BB * &front() { return m_listBB.front();}
|
||||||
|
void nodeSplitting()
|
||||||
|
{
|
||||||
|
/* Converts the irreducible graph G into an equivalent reducible one, by
|
||||||
|
* means of node splitting. */
|
||||||
|
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
|
||||||
|
}
|
||||||
|
void push_back(BB *v) { m_listBB.push_back(v);}
|
||||||
|
};
|
||||||
struct Function : public llvm::ilist_node<Function>
|
struct Function : public llvm::ilist_node<Function>
|
||||||
{
|
{
|
||||||
typedef llvm::iplist<BB> BasicBlockListType;
|
typedef llvm::iplist<BB> BasicBlockListType;
|
||||||
@ -109,6 +128,7 @@ public:
|
|||||||
|
|
||||||
/* Icodes and control flow graph */
|
/* Icodes and control flow graph */
|
||||||
CIcodeRec Icode; /* Object with ICODE records */
|
CIcodeRec Icode; /* Object with ICODE records */
|
||||||
|
FunctionCfg m_actual_cfg;
|
||||||
std::list<BB*> m_cfg; /* Ptr. to BB list/CFG */
|
std::list<BB*> m_cfg; /* Ptr. to BB list/CFG */
|
||||||
std::vector<BB*> m_dfsLast;
|
std::vector<BB*> m_dfsLast;
|
||||||
std::list<BB*> heldBBs;
|
std::list<BB*> heldBBs;
|
||||||
@ -118,9 +138,9 @@ public:
|
|||||||
bool hasCase; /* Procedure has a case node */
|
bool hasCase; /* Procedure has a case node */
|
||||||
|
|
||||||
/* For interprocedural live analysis */
|
/* For interprocedural live analysis */
|
||||||
std::bitset<32> liveIn; /* Registers used before defined */
|
LivenessSet liveIn; /* Registers used before defined */
|
||||||
std::bitset<32> liveOut; /* Registers that may be used in successors */
|
LivenessSet liveOut; /* Registers that may be used in successors */
|
||||||
bool liveAnal; /* Procedure has been analysed already */
|
bool liveAnal; /* Procedure has been analysed already */
|
||||||
|
|
||||||
Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
|
Function(void */*ty*/=0) : procEntry(0),depth(0),flg(0),cbParam(0),m_cfg(0),m_dfsLast(0),numBBs(0),
|
||||||
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
|
hasCase(false),liveIn(0),liveOut(0),liveAnal(0)//,next(0),prev(0)
|
||||||
@ -140,7 +160,7 @@ public:
|
|||||||
void writeProcComments();
|
void writeProcComments();
|
||||||
void lowLevelAnalysis();
|
void lowLevelAnalysis();
|
||||||
void bindIcodeOff();
|
void bindIcodeOff();
|
||||||
void dataFlow(std::bitset<32> &liveOut);
|
void dataFlow(LivenessSet &liveOut);
|
||||||
void compressCFG();
|
void compressCFG();
|
||||||
void highLevelGen();
|
void highLevelGen();
|
||||||
void structure(derSeq *derivedG);
|
void structure(derSeq *derivedG);
|
||||||
@ -166,7 +186,7 @@ public:
|
|||||||
void displayStats();
|
void displayStats();
|
||||||
void processHliCall(COND_EXPR *exp, iICODE picode);
|
void processHliCall(COND_EXPR *exp, iICODE picode);
|
||||||
|
|
||||||
void preprocessReturnDU(std::bitset<32> &_liveOut);
|
void preprocessReturnDU(LivenessSet &_liveOut);
|
||||||
protected:
|
protected:
|
||||||
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
|
void extractJumpTableRange(ICODE& pIcode, STATE *pstate, JumpTable &table);
|
||||||
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
bool followAllTableEntries(JumpTable &table, uint32_t cs, ICODE &pIcode, CALL_GRAPH *pcallGraph, STATE *pstate);
|
||||||
@ -190,7 +210,7 @@ protected:
|
|||||||
void findExps();
|
void findExps();
|
||||||
void genDU1();
|
void genDU1();
|
||||||
void elimCondCodes();
|
void elimCondCodes();
|
||||||
void liveRegAnalysis(std::bitset<32> &in_liveOut);
|
void liveRegAnalysis(LivenessSet &in_liveOut);
|
||||||
void findIdioms();
|
void findIdioms();
|
||||||
void propLong();
|
void propLong();
|
||||||
void genLiveKtes();
|
void genLiveKtes();
|
||||||
|
|||||||
@ -7,8 +7,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include <boost/range.hpp>
|
|
||||||
static const int operandSize=20;
|
static const int operandSize=20;
|
||||||
/* The following definitions and types define the Conditional Expression
|
/* The following definitions and types define the Conditional Expression
|
||||||
* attributed syntax tree, as defined by the following EBNF:
|
* attributed syntax tree, as defined by the following EBNF:
|
||||||
|
|||||||
@ -62,10 +62,10 @@ typedef struct { /* Command line option flags */
|
|||||||
extern OPTION option; /* Command line options */
|
extern OPTION option; /* Command line options */
|
||||||
|
|
||||||
#include "BinaryImage.h"
|
#include "BinaryImage.h"
|
||||||
extern std::bitset<32> duReg[30]; /* def/use bits for registers */
|
extern LivenessSet duReg[30]; /* def/use bits for registers */
|
||||||
|
|
||||||
//extern uint32_t duReg[30]; /* def/use bits for registers */
|
//extern uint32_t duReg[30]; /* def/use bits for registers */
|
||||||
extern std::bitset<32> maskDuReg[30]; /* masks off du bits for regs */
|
extern LivenessSet maskDuReg[30]; /* masks off du bits for regs */
|
||||||
|
|
||||||
/* Registers used by icode instructions */
|
/* Registers used by icode instructions */
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
/****************************************************************************
|
/*
|
||||||
* dcc project disassembler header
|
***************************************************************************
|
||||||
* (C) Mike van Emmerik
|
dcc project disassembler header
|
||||||
****************************************************************************/
|
(C) Mike van Emmerik
|
||||||
|
***************************************************************************
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "bundle.h"
|
#include "bundle.h"
|
||||||
@ -32,24 +33,6 @@ public:
|
|||||||
|
|
||||||
#define EXT 0x100 /* "Extended" flag */
|
#define EXT 0x100 /* "Extended" flag */
|
||||||
|
|
||||||
#ifdef __MSDOS__
|
|
||||||
#define KEY_DOWN EXT+'P'
|
|
||||||
#define KEY_LEFT EXT+'K'
|
|
||||||
#define KEY_UP EXT+'H'
|
|
||||||
#define KEY_RIGHT EXT+'M'
|
|
||||||
#define KEY_NPAGE EXT+'Q'
|
|
||||||
#define KEY_PPAGE EXT+'I'
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _CONSOLE
|
|
||||||
#define KEY_DOWN 0x50 /* Same as keypad scancodes */
|
|
||||||
#define KEY_LEFT 0x4B
|
|
||||||
#define KEY_UP 0x48
|
|
||||||
#define KEY_RIGHT 0x4D
|
|
||||||
#define KEY_NPAGE 0x51
|
|
||||||
#define KEY_PPAGE 0x49
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __UNIX__
|
#ifdef __UNIX__
|
||||||
#define KEY_DOWN EXT+'B'
|
#define KEY_DOWN EXT+'B'
|
||||||
#define KEY_LEFT EXT+'D'
|
#define KEY_LEFT EXT+'D'
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
/***************************************************************************
|
/*
|
||||||
|
|
||||||
|
=**************************************************************************
|
||||||
* File : dosdcc.h
|
* File : dosdcc.h
|
||||||
* Purpose : include file for files decompiled by dcc.
|
* Purpose : include file for files decompiled by dcc.
|
||||||
* Copyright (c) Cristina Cifuentes - QUT - 1992
|
* Copyright (c) Cristina Cifuentes - QUT - 1992
|
||||||
**************************************************************************/
|
*************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
/* Type definitions for intel 80x86 architecture */
|
/* Type definitions for intel 80x86 architecture */
|
||||||
typedef unsigned int uint16_t; /* 16 bits */
|
typedef unsigned int uint16_t; /* 16 bits */
|
||||||
@ -18,7 +21,7 @@ typedef struct {
|
|||||||
uint16_t lowBitWord : 1;
|
uint16_t lowBitWord : 1;
|
||||||
uint16_t filler1 : 6;
|
uint16_t filler1 : 6;
|
||||||
uint16_t highBitByte : 1;
|
uint16_t highBitByte : 1;
|
||||||
/* high uint8_t */
|
/* high uint8_t */
|
||||||
uint16_t lowBitByte : 1;
|
uint16_t lowBitByte : 1;
|
||||||
uint16_t filler2 : 6;
|
uint16_t filler2 : 6;
|
||||||
uint16_t highBitWord : 1;
|
uint16_t highBitWord : 1;
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
/*****************************************************************************
|
/*
|
||||||
|
****************************************************************************
|
||||||
* CFG, BB and interval related definitions
|
* CFG, BB and interval related definitions
|
||||||
* (C) Cristina Cifuentes
|
* ( C ) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************
|
||||||
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
|
||||||
struct Function;
|
struct Function;
|
||||||
/* Types of basic block nodes */
|
/* Types of basic block nodes */
|
||||||
/* Real basic blocks: type defined according to their out-edges */
|
/* Real basic blocks: type defined according to their out-edges */
|
||||||
@ -55,6 +58,7 @@ enum eNodeHeaderType
|
|||||||
#define ELSE 1 /* else edge */
|
#define ELSE 1 /* else edge */
|
||||||
|
|
||||||
/* Basic Block (BB) flags */
|
/* Basic Block (BB) flags */
|
||||||
|
|
||||||
#define INVALID_BB 0x0001 /* BB is not valid any more */
|
#define INVALID_BB 0x0001 /* BB is not valid any more */
|
||||||
#define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */
|
#define IS_LATCH_NODE 0x0002 /* BB is the latching node of a loop */
|
||||||
|
|
||||||
@ -64,8 +68,8 @@ typedef std::list<BB *> queue;
|
|||||||
|
|
||||||
struct interval
|
struct interval
|
||||||
{
|
{
|
||||||
uint8_t numInt; /* # of the interval */
|
uint8_t numInt; /* # of the interval */
|
||||||
uint8_t numOutEdges; /* Number of out edges */
|
uint8_t numOutEdges; /* Number of out edges */
|
||||||
queue nodes; /* Nodes of the interval*/
|
queue nodes; /* Nodes of the interval*/
|
||||||
queue::iterator currNode; /* Current node */
|
queue::iterator currNode; /* Current node */
|
||||||
interval *next; /* Next interval */
|
interval *next; /* Next interval */
|
||||||
@ -76,6 +80,7 @@ struct interval
|
|||||||
currNode=nodes.end();
|
currNode=nodes.end();
|
||||||
next=0;
|
next=0;
|
||||||
}
|
}
|
||||||
|
void appendNodeInt(queue &pqH, BB *node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -83,6 +88,7 @@ struct interval
|
|||||||
struct derSeq_Entry
|
struct derSeq_Entry
|
||||||
{
|
{
|
||||||
BB * Gi; /* Graph pointer */
|
BB * Gi; /* Graph pointer */
|
||||||
|
std::list<interval *> m_intervals;
|
||||||
interval * Ii; /* Interval list of Gi */
|
interval * Ii; /* Interval list of Gi */
|
||||||
derSeq_Entry() : Gi(0),Ii(0)
|
derSeq_Entry() : Gi(0),Ii(0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -9,12 +9,9 @@
|
|||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <llvm/ADT/ilist.h>
|
#include <llvm/ADT/ilist.h>
|
||||||
#include <llvm/ADT/ilist_node.h>
|
#include <llvm/ADT/ilist_node.h>
|
||||||
#include <llvm/CodeGen/MachineInstr.h>
|
|
||||||
#include <llvm/MC/MCInst.h>
|
#include <llvm/MC/MCInst.h>
|
||||||
#include <llvm/MC/MCAsmInfo.h>
|
|
||||||
#include <llvm/Value.h>
|
|
||||||
#include <llvm/Instruction.h>
|
#include <llvm/Instruction.h>
|
||||||
#include <boost/range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include "libdis.h"
|
#include "libdis.h"
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
#include "state.h" // State depends on INDEXBASE, but later need STATE
|
||||||
@ -32,7 +29,45 @@ typedef std::list<ICODE>::iterator iICODE;
|
|||||||
typedef std::list<ICODE>::reverse_iterator riICODE;
|
typedef std::list<ICODE>::reverse_iterator riICODE;
|
||||||
typedef boost::iterator_range<iICODE> rCODE;
|
typedef boost::iterator_range<iICODE> rCODE;
|
||||||
|
|
||||||
extern std::bitset<32> duReg[30];
|
struct LivenessSet : public std::bitset<32>
|
||||||
|
{
|
||||||
|
LivenessSet(int val=0) : std::bitset<32>(val) {}
|
||||||
|
LivenessSet(const LivenessSet &other)
|
||||||
|
{
|
||||||
|
(std::bitset<32> &)*this = (std::bitset<32> &)other;
|
||||||
|
}
|
||||||
|
LivenessSet(const std::bitset<32> &other)
|
||||||
|
{
|
||||||
|
(std::bitset<32> &)*this = other;
|
||||||
|
}
|
||||||
|
// LivenessSet(LivenessSet &&other) : LivenessSet()
|
||||||
|
// {
|
||||||
|
// swap(*this,other);
|
||||||
|
// }
|
||||||
|
LivenessSet &operator=(LivenessSet other)
|
||||||
|
{
|
||||||
|
swap(*this,other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
friend void swap(LivenessSet& first, LivenessSet& second) // nothrow
|
||||||
|
{
|
||||||
|
// enable ADL (not necessary in our case, but good practice)
|
||||||
|
using std::swap;
|
||||||
|
|
||||||
|
// by swapping the members of two classes,
|
||||||
|
// the two classes are effectively swapped
|
||||||
|
swap((std::bitset<32> &)first, (std::bitset<32> &)second);
|
||||||
|
}
|
||||||
|
|
||||||
|
LivenessSet &setReg(int r);
|
||||||
|
LivenessSet &addReg(int r);
|
||||||
|
bool testReg(int r)
|
||||||
|
{
|
||||||
|
return test(r-rAX);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern LivenessSet duReg[30];
|
||||||
/* uint8_t and uint16_t registers */
|
/* uint8_t and uint16_t registers */
|
||||||
|
|
||||||
/* Def/use of flags - low 4 bits represent flags */
|
/* Def/use of flags - low 4 bits represent flags */
|
||||||
@ -350,14 +385,13 @@ public:
|
|||||||
use.reset();
|
use.reset();
|
||||||
lastDefRegi.reset();
|
lastDefRegi.reset();
|
||||||
}
|
}
|
||||||
std::bitset<32> def; // For Registers: position in bitset is reg index
|
LivenessSet def; // For Registers: position in bitset is reg index
|
||||||
std::bitset<32> use; // For Registers: position in uint32_t is reg index
|
LivenessSet use; // For Registers: position in uint32_t is reg index
|
||||||
std::bitset<32> lastDefRegi;// Bit set if last def of this register in BB
|
LivenessSet lastDefRegi;// Bit set if last def of this register in BB
|
||||||
void addDefinedAndUsed(eReg r)
|
void addDefinedAndUsed(eReg r)
|
||||||
{
|
{
|
||||||
def |= duReg[r];
|
def.addReg(r);
|
||||||
use |= duReg[r];
|
use.addReg(r);
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct DU1
|
struct DU1
|
||||||
|
|||||||
@ -73,7 +73,7 @@ public:
|
|||||||
ostr << regName(eReg(j))<<" ";
|
ostr << regName(eReg(j))<<" ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static eReg subRegH(eReg reg); //TODO: move these into machine_x86
|
static eReg subRegH(eReg reg);
|
||||||
static eReg subRegL(eReg reg);
|
static eReg subRegL(eReg reg);
|
||||||
|
|
||||||
static bool isMemOff(eReg r);
|
static bool isMemOff(eReg r);
|
||||||
|
|||||||
@ -3,10 +3,7 @@
|
|||||||
hashing functions
|
hashing functions
|
||||||
* (C) Mike van Emmerik
|
* (C) Mike van Emmerik
|
||||||
*/
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
//#define bool unsigned char
|
|
||||||
#define uint8_t unsigned char
|
|
||||||
#define uint16_t unsigned short
|
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
void hashCleanup(void); /* Frees memory allocated by hashParams() */
|
void hashCleanup(void); /* Frees memory allocated by hashParams() */
|
||||||
|
|||||||
@ -36,7 +36,7 @@ BB *BB::Create(const rCODE &r,uint8_t _nodeType, Function *parent)
|
|||||||
//setInBB should automatically handle if our range is empty
|
//setInBB should automatically handle if our range is empty
|
||||||
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
parent->Icode.SetInBB(pnewBB->instructions, pnewBB);
|
||||||
parent->heldBBs.push_back(pnewBB);
|
parent->heldBBs.push_back(pnewBB);
|
||||||
parent->m_cfg.push_back(pnewBB);
|
parent->m_actual_cfg.push_back(pnewBB);
|
||||||
pnewBB->Parent = parent;
|
pnewBB->Parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,13 +127,11 @@ void BB::displayDfs()
|
|||||||
pb.BBptr->displayDfs();
|
pb.BBptr->displayDfs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Recursive procedure that writes the code for the given procedure, pointed
|
/** Recursive procedure that writes the code for the given procedure, pointed
|
||||||
* to by pBB.
|
to by pBB.
|
||||||
* Parameters: pBB: pointer to the cfg.
|
\param indLevel indentation level - used for formatting.
|
||||||
* Icode: pointer to the Icode array for the cfg graph of the
|
\param numLoc: last # assigned to local variables
|
||||||
* current procedure.
|
*/
|
||||||
* indLevel: indentation level - used for formatting.
|
|
||||||
* numLoc: last # assigned to local variables */
|
|
||||||
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond)
|
ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&latch, boolT &repCond)
|
||||||
{
|
{
|
||||||
latch = pProc->m_dfsLast[this->latchNode];
|
latch = pProc->m_dfsLast[this->latchNode];
|
||||||
@ -177,6 +175,7 @@ ICODE* BB::writeLoopHeader(int &indLevel, Function* pProc, int *numLoc, BB *&lat
|
|||||||
|
|
||||||
case ENDLESS_TYPE:
|
case ENDLESS_TYPE:
|
||||||
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
|
ostr << "\n"<<indentStr(indLevel)<<"for (;;) {\n";
|
||||||
|
picode = &latch->back();
|
||||||
}
|
}
|
||||||
cCode.appendCode(ostr.str());
|
cCode.appendCode(ostr.str());
|
||||||
stats.numHLIcode += 1;
|
stats.numHLIcode += 1;
|
||||||
@ -226,7 +225,7 @@ void BB::writeCode (int indLevel, Function * pProc , int *numLoc,int _latchNode,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Check type of loop/node and process code */
|
/* Check type of loop/node and process code */
|
||||||
if ( loopType) /* there is a loop */
|
if ( loopType ) /* there is a loop */
|
||||||
{
|
{
|
||||||
assert(latch);
|
assert(latch);
|
||||||
if (this != latch) /* loop is over several bbs */
|
if (this != latch) /* loop is over several bbs */
|
||||||
@ -391,16 +390,16 @@ void BB::writeBB(std::ostream &ostr,int lev, Function * pProc, int *numLoc)
|
|||||||
|
|
||||||
iICODE BB::begin()
|
iICODE BB::begin()
|
||||||
{
|
{
|
||||||
return instructions.begin();//range_start;
|
return instructions.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
iICODE BB::end() const
|
iICODE BB::end() const
|
||||||
{
|
{
|
||||||
return instructions.end();//range_end
|
return instructions.end();
|
||||||
}
|
}
|
||||||
ICODE &BB::back()
|
ICODE &BB::back()
|
||||||
{
|
{
|
||||||
return instructions.back();//*rbegin();
|
return instructions.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t BB::size()
|
size_t BB::size()
|
||||||
@ -411,7 +410,7 @@ size_t BB::size()
|
|||||||
|
|
||||||
ICODE &BB::front()
|
ICODE &BB::front()
|
||||||
{
|
{
|
||||||
return instructions.front();//*begin();
|
return instructions.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
riICODE BB::rbegin()
|
riICODE BB::rbegin()
|
||||||
|
|||||||
@ -43,15 +43,14 @@ void ICODE::setRegDU (eReg regi, operDu du_in)
|
|||||||
switch (du_in)
|
switch (du_in)
|
||||||
{
|
{
|
||||||
case eDEF:
|
case eDEF:
|
||||||
du.def |= duReg[regi];
|
du.def.addReg(regi);
|
||||||
du1.numRegsDef++;
|
du1.numRegsDef++;
|
||||||
break;
|
break;
|
||||||
case eUSE:
|
case eUSE:
|
||||||
du.use |= duReg[regi];
|
du.use.addReg(regi);
|
||||||
break;
|
break;
|
||||||
case USE_DEF:
|
case USE_DEF:
|
||||||
du.def |= duReg[regi];
|
du.addDefinedAndUsed(regi);
|
||||||
du.use |= duReg[regi];
|
|
||||||
du1.numRegsDef++;
|
du1.numRegsDef++;
|
||||||
break;
|
break;
|
||||||
case NONE: /* do nothing */
|
case NONE: /* do nothing */
|
||||||
|
|||||||
@ -266,7 +266,7 @@ void Function::codeGen (std::ostream &fs)
|
|||||||
}
|
}
|
||||||
else /* generate C */
|
else /* generate C */
|
||||||
{
|
{
|
||||||
m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);
|
m_actual_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
cCode.appendCode( "}\n\n");
|
cCode.appendCode( "}\n\n");
|
||||||
|
|||||||
@ -337,8 +337,7 @@ void SetupLibCheck(void)
|
|||||||
PatLen, /* The length of the pattern to be hashed */
|
PatLen, /* The length of the pattern to be hashed */
|
||||||
256, /* The character set of the pattern (0-FF) */
|
256, /* The character set of the pattern (0-FF) */
|
||||||
0, /* Minimum pattern character value */
|
0, /* Minimum pattern character value */
|
||||||
numVert); /* Specifies c, the sparseness of the graph.
|
numVert); /* Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details */
|
||||||
See Czech, Havas and Majewski for details */
|
|
||||||
T1base = g_pattern_hasher.readT1();
|
T1base = g_pattern_hasher.readT1();
|
||||||
T2base = g_pattern_hasher.readT2();
|
T2base = g_pattern_hasher.readT2();
|
||||||
g = g_pattern_hasher.readG();
|
g = g_pattern_hasher.readG();
|
||||||
@ -462,8 +461,7 @@ bool LibCheck(Function & pProc)
|
|||||||
//memmove(pat, &prog.Image[fileOffset], PATLEN);
|
//memmove(pat, &prog.Image[fileOffset], PATLEN);
|
||||||
fixWildCards(pat); /* Fix wild cards in the copy */
|
fixWildCards(pat); /* Fix wild cards in the copy */
|
||||||
h = g_pattern_hasher.hash(pat); /* Hash the found proc */
|
h = g_pattern_hasher.hash(pat); /* Hash the found proc */
|
||||||
/* We always have to compare keys, because the hash function will
|
/* We always have to compare keys, because the hash function will always return a valid index */
|
||||||
always return a valid index */
|
|
||||||
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
|
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)
|
||||||
{
|
{
|
||||||
/* We have a match. Save the name, if not already set */
|
/* We have a match. Save the name, if not already set */
|
||||||
@ -494,13 +492,13 @@ bool LibCheck(Function & pProc)
|
|||||||
pProc.flg |= PROC_IS_FUNC;
|
pProc.flg |= PROC_IS_FUNC;
|
||||||
switch (pProc.retVal.type) {
|
switch (pProc.retVal.type) {
|
||||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
||||||
pProc.liveOut = duReg[rDX] | duReg[rAX];
|
pProc.liveOut.setReg(rDX) |= duReg[rAX];
|
||||||
break;
|
break;
|
||||||
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
||||||
pProc.liveOut = duReg[rAX];
|
pProc.liveOut.setReg(rAX);
|
||||||
break;
|
break;
|
||||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||||
pProc.liveOut = duReg[rAL];
|
pProc.liveOut.setReg(rAL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,"Unknown retval type %d in LibCheck\n",pProc.retVal.type);
|
fprintf(stderr,"Unknown retval type %d in LibCheck\n",pProc.retVal.type);
|
||||||
|
|||||||
211
src/dataflow.cpp
211
src/dataflow.cpp
@ -45,7 +45,6 @@ void ExpStack::init()
|
|||||||
expStk.clear();
|
expStk.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Pushes the given expression onto the local stack (expStk). */
|
/* Pushes the given expression onto the local stack (expStk). */
|
||||||
void ExpStack::push(COND_EXPR *expr)
|
void ExpStack::push(COND_EXPR *expr)
|
||||||
{
|
{
|
||||||
@ -114,7 +113,7 @@ static COND_EXPR *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i,
|
|||||||
/* Eliminates all condition codes and generates new hlIcode instructions */
|
/* Eliminates all condition codes and generates new hlIcode instructions */
|
||||||
void Function::elimCondCodes ()
|
void Function::elimCondCodes ()
|
||||||
{
|
{
|
||||||
// int i;
|
// int i;
|
||||||
|
|
||||||
uint8_t use; /* Used flags bit vector */
|
uint8_t use; /* Used flags bit vector */
|
||||||
uint8_t def; /* Defined flags bit vector */
|
uint8_t def; /* Defined flags bit vector */
|
||||||
@ -125,19 +124,11 @@ void Function::elimCondCodes ()
|
|||||||
//BB * pBB; /* Pointer to BBs in dfs last ordering */
|
//BB * pBB; /* Pointer to BBs in dfs last ordering */
|
||||||
riICODE useAt; /* Instruction that used flag */
|
riICODE useAt; /* Instruction that used flag */
|
||||||
riICODE defAt; /* Instruction that defined 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()) );
|
auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
|
||||||
for( BB * pBB : valid_reversed_bbs)
|
for( BB * pBB : valid_reversed_bbs)
|
||||||
{
|
{
|
||||||
|
//auto reversed_instructions = pBB->range() | reversed;
|
||||||
// for (size_t i = 0; i < numBBs; i++)
|
|
||||||
// {
|
|
||||||
// pBB = m_dfsLast[i];
|
|
||||||
// if (pBB->flg & INVALID_BB)
|
|
||||||
// continue; /* Do not process invalid BBs */
|
|
||||||
// auto v(pBB | boost::adaptors::reversed);
|
|
||||||
// for (const ICODE &useAt : v)
|
|
||||||
// {}
|
|
||||||
for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++)
|
for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++)
|
||||||
{
|
{
|
||||||
llIcode useAtOp = llIcode(useAt->ll()->getOpcode());
|
llIcode useAtOp = llIcode(useAt->ll()->getOpcode());
|
||||||
@ -234,7 +225,6 @@ void Function::elimCondCodes ()
|
|||||||
else if (defAt == pBB->rend())
|
else if (defAt == pBB->rend())
|
||||||
{
|
{
|
||||||
reportError(DEF_NOT_FOUND,useAtOp);
|
reportError(DEF_NOT_FOUND,useAtOp);
|
||||||
//fatalError (DEF_NOT_FOUND, Icode.getOpcode(useAt-1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,7 +240,7 @@ void Function::elimCondCodes ()
|
|||||||
void Function::genLiveKtes ()
|
void Function::genLiveKtes ()
|
||||||
{
|
{
|
||||||
BB * pbb;
|
BB * pbb;
|
||||||
bitset<32> liveUse, def;
|
LivenessSet liveUse, def;
|
||||||
|
|
||||||
for (size_t i = 0; i < numBBs; i++)
|
for (size_t i = 0; i < numBBs; i++)
|
||||||
{
|
{
|
||||||
@ -276,15 +266,15 @@ void Function::genLiveKtes ()
|
|||||||
/* Generates the liveIn() and liveOut() sets for each basic block via an
|
/* Generates the liveIn() and liveOut() sets for each basic block via an
|
||||||
* iterative approach.
|
* iterative approach.
|
||||||
* Propagates register usage information to the procedure call. */
|
* Propagates register usage information to the procedure call. */
|
||||||
void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
void Function::liveRegAnalysis (LivenessSet &in_liveOut)
|
||||||
{
|
{
|
||||||
using namespace boost::adaptors;
|
using namespace boost::adaptors;
|
||||||
using namespace boost::assign;
|
using namespace boost::assign;
|
||||||
BB * pbb=0; /* pointer to current basic block */
|
//BB * pbb=0; /* pointer to current basic block */
|
||||||
Function * pcallee; /* invoked subroutine */
|
Function * pcallee; /* invoked subroutine */
|
||||||
//ICODE *ticode /* icode that invokes a subroutine */
|
//ICODE *ticode /* icode that invokes a subroutine */
|
||||||
;
|
;
|
||||||
std::bitset<32> prevLiveOut, /* previous live out */
|
LivenessSet prevLiveOut, /* previous live out */
|
||||||
prevLiveIn; /* previous live in */
|
prevLiveIn; /* previous live in */
|
||||||
boolT change; /* is there change in the live sets?*/
|
boolT change; /* is there change in the live sets?*/
|
||||||
|
|
||||||
@ -297,9 +287,8 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
|||||||
/* Process nodes in reverse postorder order */
|
/* Process nodes in reverse postorder order */
|
||||||
change = false;
|
change = false;
|
||||||
auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
|
auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
|
||||||
for( BB * _pbb : valid_reversed_bbs)
|
for( BB * pbb : valid_reversed_bbs) // for each valid pbb in reversed dfs order
|
||||||
{
|
{
|
||||||
pbb = _pbb;//*iBB;//m_dfsLast[i-1];
|
|
||||||
|
|
||||||
/* Get current liveIn() and liveOut() sets */
|
/* Get current liveIn() and liveOut() sets */
|
||||||
prevLiveIn = pbb->liveIn;
|
prevLiveIn = pbb->liveIn;
|
||||||
@ -349,22 +338,22 @@ void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
|
|||||||
)
|
)
|
||||||
pbb->liveOut = pcallee->liveOut;
|
pbb->liveOut = pcallee->liveOut;
|
||||||
else
|
else
|
||||||
pbb->liveOut = 0;
|
pbb->liveOut.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((! (pcallee->flg & PROC_ISLIB)) || (pbb->liveOut != 0))
|
if ((! (pcallee->flg & PROC_ISLIB)) || ( pbb->liveOut.any() ))
|
||||||
{
|
{
|
||||||
switch (pcallee->retVal.type) {
|
switch (pcallee->retVal.type) {
|
||||||
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
|
||||||
ticode.du1.numRegsDef = 2;
|
ticode.du1.numRegsDef = 2;
|
||||||
break;
|
break;
|
||||||
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
|
||||||
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
|
||||||
ticode.du1.numRegsDef = 1;
|
ticode.du1.numRegsDef = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ticode.du1.numRegsDef = 0;
|
ticode.du1.numRegsDef = 0;
|
||||||
//fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type);
|
//fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type);
|
||||||
} /*eos*/
|
} /*eos*/
|
||||||
|
|
||||||
/* Propagate def/use results to calling icode */
|
/* 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) */
|
/* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
|
||||||
pbb->liveIn = pbb->liveUse | (pbb->liveOut & ~pbb->def);
|
pbb->liveIn = LivenessSet(pbb->liveUse | (pbb->liveOut & ~pbb->def));
|
||||||
|
|
||||||
/* Check if live sets have been modified */
|
/* Check if live sets have been modified */
|
||||||
if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
|
if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
|
||||||
change = true;
|
change = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BB *pbb = m_dfsLast.front();
|
||||||
/* Propagate liveIn(b) to procedure header */
|
/* Propagate liveIn(b) to procedure header */
|
||||||
if (pbb->liveIn != 0) /* uses registers */
|
if (pbb->liveIn.any()) /* uses registers */
|
||||||
liveIn = pbb->liveIn;
|
liveIn = pbb->liveIn;
|
||||||
|
|
||||||
/* Remove any references to register variables */
|
/* Remove any references to register variables */
|
||||||
if (flg & SI_REGVAR)
|
if (flg & SI_REGVAR)
|
||||||
{
|
{
|
||||||
liveIn &= maskDuReg[rSI];
|
liveIn.set(rSI,0);
|
||||||
pbb->liveIn &= maskDuReg[rSI];
|
pbb->liveIn.set(rSI,0);
|
||||||
}
|
}
|
||||||
if (flg & DI_REGVAR)
|
if (flg & DI_REGVAR)
|
||||||
{
|
{
|
||||||
liveIn &= maskDuReg[rDI];
|
liveIn.set(rDI,0);
|
||||||
pbb->liveIn &= maskDuReg[rDI];
|
pbb->liveIn.set(rDI,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,13 +423,13 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
|||||||
|
|
||||||
/* Check if last definition of this register */
|
/* Check if last definition of this register */
|
||||||
if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
|
if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
|
||||||
start_at->du.lastDefRegi |= duReg[regi];
|
start_at->du.lastDefRegi.addReg(regi);
|
||||||
}
|
}
|
||||||
else /* only 1 instruction in this basic block */
|
else /* only 1 instruction in this basic block */
|
||||||
{
|
{
|
||||||
/* Check if last definition of this register */
|
/* Check if last definition of this register */
|
||||||
if ((liveOut & duReg[regi]).any())
|
if ((liveOut & duReg[regi]).any())
|
||||||
start_at->du.lastDefRegi |= duReg[regi];
|
start_at->du.lastDefRegi.addReg(regi);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -448,10 +437,10 @@ bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
|
|||||||
* that are functions. The target icode is in the
|
* that are functions. The target icode is in the
|
||||||
* next basic block (unoptimized code) or somewhere else
|
* next basic block (unoptimized code) or somewhere else
|
||||||
* on optimized code. */
|
* on optimized code. */
|
||||||
void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
|
void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, ICODE &picode)
|
||||||
{
|
{
|
||||||
if ((picode->hl()->opcode == HLI_CALL) &&
|
if ((picode.hl()->opcode == HLI_CALL) &&
|
||||||
(picode->hl()->call.proc->flg & PROC_IS_FUNC))
|
(picode.hl()->call.proc->flg & PROC_IS_FUNC))
|
||||||
{
|
{
|
||||||
BB *tbb = this->edges[0].BBptr;
|
BB *tbb = this->edges[0].BBptr;
|
||||||
auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level);
|
auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level);
|
||||||
@ -459,7 +448,7 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
|
|||||||
{
|
{
|
||||||
/* if used, get icode index */
|
/* if used, get icode index */
|
||||||
if ((iter->du.use & duReg[regi]).any())
|
if ((iter->du.use & duReg[regi]).any())
|
||||||
picode->du1.recordUse(defRegIdx,iter.base());
|
picode.du1.recordUse(defRegIdx,iter.base());
|
||||||
/* if defined, stop finding uses for this reg */
|
/* if defined, stop finding uses for this reg */
|
||||||
if ((iter->du.def & duReg[regi]).any())
|
if ((iter->du.def & duReg[regi]).any())
|
||||||
break;
|
break;
|
||||||
@ -468,8 +457,8 @@ void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
|
|||||||
/* if not used in this basic block, check if the
|
/* if not used in this basic block, check if the
|
||||||
* register is live out, if so, make it the last
|
* register is live out, if so, make it the last
|
||||||
* definition of this register */
|
* definition of this register */
|
||||||
if ( picode->du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
|
if ( picode.du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
|
||||||
picode->du.lastDefRegi |= duReg[regi];
|
picode.du.lastDefRegi.addReg(regi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +491,7 @@ void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* liveOut */
|
else /* liveOut */
|
||||||
picode->du.lastDefRegi |= duReg[regi];
|
picode->du.lastDefRegi.addReg(regi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +518,7 @@ void BB::genDU1()
|
|||||||
if(FindUseBeforeDef(regi,defRegIdx, picode.base()))
|
if(FindUseBeforeDef(regi,defRegIdx, picode.base()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ProcessUseDefForFunc(regi, defRegIdx,picode.base());
|
ProcessUseDefForFunc(regi, defRegIdx,*picode);
|
||||||
RemoveUnusedDefs(regi, defRegIdx, picode.base());
|
RemoveUnusedDefs(regi, defRegIdx, picode.base());
|
||||||
|
|
||||||
defRegIdx++;
|
defRegIdx++;
|
||||||
@ -734,47 +723,47 @@ void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode
|
|||||||
HLTYPE &t_hl(*ticode->hl());
|
HLTYPE &t_hl(*ticode->hl());
|
||||||
switch (t_hl.opcode)
|
switch (t_hl.opcode)
|
||||||
{
|
{
|
||||||
case HLI_ASSIGN:
|
case HLI_ASSIGN:
|
||||||
if(isLong)
|
if(isLong)
|
||||||
{
|
{
|
||||||
forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx,
|
forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx,
|
||||||
p_hl.asgn.rhs, picode,ticode,
|
p_hl.asgn.rhs, picode,ticode,
|
||||||
&numHlIcodes);
|
&numHlIcodes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes);
|
this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
case HLI_JCOND: case HLI_PUSH: case HLI_RET:
|
||||||
if(isLong)
|
if(isLong)
|
||||||
{
|
{
|
||||||
res = COND_EXPR::insertSubTreeLongReg (
|
res = COND_EXPR::insertSubTreeLongReg (
|
||||||
p_hl.asgn.rhs,
|
p_hl.asgn.rhs,
|
||||||
&t_hl.exp.v,
|
&t_hl.exp.v,
|
||||||
p_hl.asgn.lhs->expr.ident.idNode.longIdx);
|
p_hl.asgn.lhs->expr.ident.idNode.longIdx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = COND_EXPR::insertSubTreeReg (
|
res = COND_EXPR::insertSubTreeReg (
|
||||||
t_hl.exp.v,
|
t_hl.exp.v,
|
||||||
p_hl.asgn.rhs,
|
p_hl.asgn.rhs,
|
||||||
id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
|
id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
|
picode->invalidate();
|
||||||
|
numHlIcodes--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLI_CALL: /* register arguments */
|
||||||
|
newRegArg ( picode, ticode);
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
numHlIcodes--;
|
numHlIcodes--;
|
||||||
}
|
break;
|
||||||
break;
|
default:
|
||||||
|
fprintf(stderr,"unhandled LOCAL_ID::processTargetIcode opcode %d\n",t_hl.opcode);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -857,8 +846,6 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>());
|
auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>());
|
||||||
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
|
for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
|
||||||
{
|
{
|
||||||
// if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() ))
|
|
||||||
// continue;
|
|
||||||
HLTYPE &_icHl(*picode->hl());
|
HLTYPE &_icHl(*picode->hl());
|
||||||
numHlIcodes++;
|
numHlIcodes++;
|
||||||
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
|
if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
|
||||||
@ -910,7 +897,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v,
|
res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v,
|
||||||
_exp,
|
_exp,
|
||||||
locals.id_arr[_icHl.expr()->expr.ident.idNode.regiIdx].id.regi,
|
locals.id_arr[_icHl.expr()->expr.ident.idNode.regiIdx].id.regi,
|
||||||
&locals);
|
&locals);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
@ -1060,7 +1047,7 @@ void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
|
|||||||
res = COND_EXPR::insertSubTreeLongReg (_exp,
|
res = COND_EXPR::insertSubTreeLongReg (_exp,
|
||||||
&ticode->hl()->exp.v,
|
&ticode->hl()->exp.v,
|
||||||
locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
|
locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
|
||||||
_retVal->id.longId.l, picode.base()));
|
_retVal->id.longId.l, picode.base()));
|
||||||
if (res) /* was substituted */
|
if (res) /* was substituted */
|
||||||
{
|
{
|
||||||
picode->invalidate();
|
picode->invalidate();
|
||||||
@ -1125,11 +1112,11 @@ void Function::findExps()
|
|||||||
g_exp_stk.init();
|
g_exp_stk.init();
|
||||||
|
|
||||||
/* Traverse tree in dfsLast order */
|
/* Traverse tree in dfsLast order */
|
||||||
// for (i = 0; i < numBBs; i++)
|
// for (i = 0; i < numBBs; i++)
|
||||||
for(BB *pbb : m_dfsLast)
|
for(BB *pbb : m_dfsLast)
|
||||||
{
|
{
|
||||||
/* Process one BB */
|
/* Process one BB */
|
||||||
// pbb = m_dfsLast[i];
|
// pbb = m_dfsLast[i];
|
||||||
if (not pbb->valid())
|
if (not pbb->valid())
|
||||||
continue;
|
continue;
|
||||||
pbb->findBBExps( this->localId, this);
|
pbb->findBBExps( this->localId, this);
|
||||||
@ -1137,25 +1124,25 @@ void Function::findExps()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
|
void Function::preprocessReturnDU(LivenessSet &_liveOut)
|
||||||
{
|
{
|
||||||
if (_liveOut.any())
|
if (_liveOut.any())
|
||||||
{
|
{
|
||||||
// int idx;
|
// int idx;
|
||||||
bool isAx, isBx, isCx, isDx;
|
bool isAx, isBx, isCx, isDx;
|
||||||
flg |= PROC_IS_FUNC;
|
flg |= PROC_IS_FUNC;
|
||||||
isAx = _liveOut.test(rAX - rAX);
|
isAx = _liveOut.testReg(rAX);
|
||||||
isBx = _liveOut.test(rBX - rAX);
|
isBx = _liveOut.testReg(rBX);
|
||||||
isCx = _liveOut.test(rCX - rAX);
|
isCx = _liveOut.testReg(rCX);
|
||||||
isDx = _liveOut.test(rDX - rAX);
|
isDx = _liveOut.testReg(rDX);
|
||||||
bool isAL = !isAx && _liveOut.test(rAL - rAX);
|
bool isAL = !isAx && _liveOut.testReg(rAL);
|
||||||
bool isAH = !isAx && _liveOut.test(rAH - rAX);
|
bool isAH = !isAx && _liveOut.testReg(rAH);
|
||||||
bool isBL = !isBx && _liveOut.test(rBL - rAX);
|
bool isBL = !isBx && _liveOut.testReg(rBL);
|
||||||
bool isBH = !isBx && _liveOut.test(rBH - rAX);
|
bool isBH = !isBx && _liveOut.testReg(rBH);
|
||||||
bool isCL = !isCx && _liveOut.test(rCL - rAX);
|
bool isCL = !isCx && _liveOut.testReg(rCL);
|
||||||
bool isCH = !isCx && _liveOut.test(rCH - rAX);
|
bool isCH = !isCx && _liveOut.testReg(rCH);
|
||||||
bool isDL = !isDx && _liveOut.test(rDL - rAX);
|
bool isDL = !isDx && _liveOut.testReg(rDL);
|
||||||
bool isDH = !isDx && _liveOut.test(rDH - rAX);
|
bool isDH = !isDx && _liveOut.testReg(rDH);
|
||||||
if(isAL && isAH)
|
if(isAL && isAH)
|
||||||
{
|
{
|
||||||
isAx = true;
|
isAx = true;
|
||||||
@ -1217,17 +1204,17 @@ void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Invokes procedures related with data flow analysis. Works on a procedure
|
/** Invokes procedures related with data flow analysis.
|
||||||
* at a time basis.
|
* Works on a procedure at a time basis.
|
||||||
* Note: indirect recursion in liveRegAnalysis is possible. */
|
\note indirect recursion in liveRegAnalysis is possible. */
|
||||||
void Function::dataFlow(std::bitset<32> &_liveOut)
|
void Function::dataFlow(LivenessSet &_liveOut)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Remove references to register variables */
|
/* Remove references to register variables */
|
||||||
if (flg & SI_REGVAR)
|
if (flg & SI_REGVAR)
|
||||||
_liveOut &= maskDuReg[rSI];
|
_liveOut.set(rSI,0);
|
||||||
if (flg & DI_REGVAR)
|
if (flg & DI_REGVAR)
|
||||||
_liveOut &= maskDuReg[rDI];
|
_liveOut.set(rDI,0);
|
||||||
|
|
||||||
/* Function - return value register(s) */
|
/* Function - return value register(s) */
|
||||||
preprocessReturnDU(_liveOut);
|
preprocessReturnDU(_liveOut);
|
||||||
|
|||||||
@ -3,10 +3,11 @@
|
|||||||
* Loads a program into simulated main memory and builds the procedure list.
|
* Loads a program into simulated main memory and builds the procedure list.
|
||||||
* (C) Cristina Cifuentes
|
* (C) Cristina Cifuentes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#define __STDC_FORMAT_MACROS
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "disassem.h"
|
#include "disassem.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@ -35,7 +35,7 @@ void Function::createCFG()
|
|||||||
* 5) Repeated string instructions
|
* 5) Repeated string instructions
|
||||||
* 6) End of procedure
|
* 6) End of procedure
|
||||||
*/
|
*/
|
||||||
int i;
|
|
||||||
BB * psBB;
|
BB * psBB;
|
||||||
BB * pBB;
|
BB * pBB;
|
||||||
iICODE pIcode = Icode.begin();
|
iICODE pIcode = Icode.begin();
|
||||||
@ -209,7 +209,7 @@ void Function::compressCFG()
|
|||||||
|
|
||||||
/* First pass over BB list removes redundant jumps of the form
|
/* First pass over BB list removes redundant jumps of the form
|
||||||
* (Un)Conditional -> Unconditional jump */
|
* (Un)Conditional -> Unconditional jump */
|
||||||
for (BB *pBB : m_cfg)
|
for (BB *pBB : m_actual_cfg) //m_cfg
|
||||||
{
|
{
|
||||||
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
|
if(pBB->inEdges.empty() || (pBB->nodeType != ONE_BRANCH && pBB->nodeType != TWO_BRANCH))
|
||||||
continue;
|
continue;
|
||||||
@ -231,18 +231,17 @@ void Function::compressCFG()
|
|||||||
/* Next is a depth-first traversal merging any FALL_NODE or
|
/* Next is a depth-first traversal merging any FALL_NODE or
|
||||||
* ONE_BRANCH that fall through to a node with that as their only
|
* ONE_BRANCH that fall through to a node with that as their only
|
||||||
* in-edge. */
|
* in-edge. */
|
||||||
m_cfg.front()->mergeFallThrough(Icode);
|
m_actual_cfg.front()->mergeFallThrough(Icode);
|
||||||
|
|
||||||
/* Remove redundant BBs created by the above compressions
|
/* Remove redundant BBs created by the above compressions
|
||||||
* and allocate in-edge arrays as required. */
|
* and allocate in-edge arrays as required. */
|
||||||
stats.numBBaft = stats.numBBbef;
|
stats.numBBaft = stats.numBBbef;
|
||||||
|
bool entry_node=true;
|
||||||
for(auto iter=m_cfg.begin(); iter!=m_cfg.end(); ++iter)
|
for(BB *pBB : m_actual_cfg)
|
||||||
{
|
{
|
||||||
BB * pBB = *iter;
|
|
||||||
if (pBB->inEdges.empty())
|
if (pBB->inEdges.empty())
|
||||||
{
|
{
|
||||||
if (iter == m_cfg.begin()) /* Init it misses out on */
|
if (entry_node) /* Init it misses out on */
|
||||||
pBB->index = UN_INIT;
|
pBB->index = UN_INIT;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -254,6 +253,7 @@ void Function::compressCFG()
|
|||||||
{
|
{
|
||||||
pBB->inEdgeCount = pBB->inEdges.size();
|
pBB->inEdgeCount = pBB->inEdges.size();
|
||||||
}
|
}
|
||||||
|
entry_node=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate storage for dfsLast[] array */
|
/* Allocate storage for dfsLast[] array */
|
||||||
@ -262,7 +262,7 @@ void Function::compressCFG()
|
|||||||
|
|
||||||
/* Now do a dfs numbering traversal and fill in the inEdges[] array */
|
/* Now do a dfs numbering traversal and fill in the inEdges[] array */
|
||||||
last = numBBs - 1;
|
last = numBBs - 1;
|
||||||
m_cfg.front()->dfsNumbering(m_dfsLast, &first, &last);
|
m_actual_cfg.front()->dfsNumbering(m_dfsLast, &first, &last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,18 +10,28 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
#define ICODE_DELTA 25
|
|
||||||
|
|
||||||
/* Masks off bits set by duReg[] */
|
/* Masks off bits set by duReg[] */
|
||||||
std::bitset<32> maskDuReg[] = { 0x00,
|
LivenessSet maskDuReg[] = { 0x00,
|
||||||
0xFEEFFE, 0xFDDFFD, 0xFBB00B, 0xF77007, /* uint16_t regs */
|
/* uint16_t regs */
|
||||||
0xFFFFEF, 0xFFFFDF, 0xFFFFBF, 0xFFFF7F,
|
0xFEEFFE, //rAX
|
||||||
0xFFFEFF, 0xFFFDFF, 0xFFFBFF, 0xFFF7FF, /* seg regs */
|
0xFDDFFD, //rCX
|
||||||
0xFFEFFF, 0xFFDFFF, 0xFFBFFF, 0xFF7FFF, /* uint8_t regs */
|
0xFBB00B, //rDX
|
||||||
0xFEFFFF, 0xFDFFFF, 0xFBFFFF, 0xF7FFFF,
|
0xF77007, //rBX
|
||||||
0xEFFFFF, /* tmp reg */
|
0xFFFFEF, //rSP
|
||||||
0xFFFFB7, 0xFFFF77, 0xFFFF9F, 0xFFFF5F, /* index regs */
|
0xFFFFDF, //rBP
|
||||||
0xFFFFBF, 0xFFFF7F, 0xFFFFDF, 0xFFFFF7 };
|
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 */
|
static char buf[lineSize]; /* Line buffer for hl icode output */
|
||||||
|
|
||||||
|
|||||||
@ -2,15 +2,12 @@
|
|||||||
// (C) 1997 Mike Van Emmerik
|
// (C) 1997 Mike Van Emmerik
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <malloc.h>
|
|
||||||
#include <memory.h>
|
|
||||||
|
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "types.h" // Common types like uint8_t, etc
|
#include "types.h" // Common types like uint8_t, etc
|
||||||
#include "ast.h" // Some icode types depend on these
|
#include "ast.h" // Some icode types depend on these
|
||||||
#include "icode.h"
|
#include "icode.h"
|
||||||
|
|
||||||
#define ICODE_DELTA 25 // Amount to allocate for new chunk
|
|
||||||
|
|
||||||
ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level;
|
ICODE::TypeFilter<HIGH_LEVEL> ICODE::select_high_level;
|
||||||
ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level;
|
ICODE::TypeAndValidFilter<HIGH_LEVEL> ICODE::select_valid_high_level;
|
||||||
@ -31,9 +28,7 @@ ICODE * CIcodeRec::addIcode(ICODE *pIcode)
|
|||||||
void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB)
|
void CIcodeRec::SetInBB(rCODE &rang, BB *pnewBB)
|
||||||
{
|
{
|
||||||
for(ICODE &ic : rang)
|
for(ICODE &ic : rang)
|
||||||
{
|
|
||||||
ic.setParent(pnewBB);
|
ic.setParent(pnewBB);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* labelSrchRepl - Searches the icodes for instruction with label = target, and
|
/* labelSrchRepl - Searches the icodes for instruction with label = target, and
|
||||||
|
|||||||
@ -16,13 +16,11 @@ bool LONGID_TYPE::srcDstRegMatch(iICODE a, iICODE b) const
|
|||||||
|
|
||||||
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
|
ID::ID() : type(TYPE_UNKNOWN),illegal(false),loc(STK_FRAME),hasMacro(false)
|
||||||
{
|
{
|
||||||
name[0]=0;
|
|
||||||
macro[0]=0;
|
macro[0]=0;
|
||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
}
|
}
|
||||||
ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
|
ID::ID(hlType t, frameType f) : type(t),illegal(false),hasMacro(false)
|
||||||
{
|
{
|
||||||
name[0]=0;
|
|
||||||
macro[0]=0;
|
macro[0]=0;
|
||||||
memset(&id,0,sizeof(id));
|
memset(&id,0,sizeof(id));
|
||||||
loc=f;
|
loc=f;
|
||||||
@ -273,7 +271,7 @@ int LOCAL_ID::newLongStk(hlType t, int offH, int offL)
|
|||||||
* number in an expression record. */
|
* number in an expression record. */
|
||||||
int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset)
|
int LOCAL_ID::newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix,operDu du, LLInst &atOffset)
|
||||||
{
|
{
|
||||||
size_t idx;
|
size_t idx = ~0; //WARNING: clients of this method might propagate this bogus value!
|
||||||
const LLOperand *pmH, *pmL;
|
const LLOperand *pmH, *pmL;
|
||||||
LLInst &p_ll(*pIcode->ll());
|
LLInst &p_ll(*pIcode->ll());
|
||||||
if (f == LOW_FIRST)
|
if (f == LOW_FIRST)
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
* dcc project procedure list builder
|
* dcc project procedure list builder
|
||||||
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
|
* (C) Cristina Cifuentes, Mike van Emmerik, Jeff Ledermann
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#define __STDC_FORMAT_MACROS
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h> /* For exit() */
|
#include <stdlib.h> /* For exit() */
|
||||||
@ -886,7 +886,7 @@ static void setBits(int16_t type, uint32_t start, uint32_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* DU bit definitions for each reg value - including index registers */
|
/* DU bit definitions for each reg value - including index registers */
|
||||||
std::bitset<32> duReg[] = { 0x00,
|
LivenessSet duReg[] = { 0x00,
|
||||||
//AH AL . . AX, BH
|
//AH AL . . AX, BH
|
||||||
0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */
|
0x11001, 0x22002, 0x44004, 0x88008, /* uint16_t regs */
|
||||||
0x10, 0x20, 0x40, 0x80,
|
0x10, 0x20, 0x40, 0x80,
|
||||||
@ -1066,7 +1066,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
case iDIV: case iIDIV:
|
case iDIV: case iIDIV:
|
||||||
use(SRC, pIcode, this, pstate, cb);
|
use(SRC, pIcode, this, pstate, cb);
|
||||||
if (cb == 1)
|
if (cb == 1)
|
||||||
pIcode.du.use |= duReg[rTMP];
|
pIcode.du.use.addReg(rTMP);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iMUL: case iIMUL:
|
case iMUL: case iIMUL:
|
||||||
@ -1076,12 +1076,12 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
use (DST, pIcode, this, pstate, cb);
|
use (DST, pIcode, this, pstate, cb);
|
||||||
if (cb == 1)
|
if (cb == 1)
|
||||||
{
|
{
|
||||||
pIcode.du.def |= duReg[rAX];
|
pIcode.du.def.addReg(rAX);
|
||||||
pIcode.du1.numRegsDef++;
|
pIcode.du1.numRegsDef++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pIcode.du.def |= (duReg[rAX] | duReg[rDX]);
|
pIcode.du.def.addReg(rAX).addReg(rDX);
|
||||||
pIcode.du1.numRegsDef += 2;
|
pIcode.du1.numRegsDef += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1093,15 +1093,15 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
cb = pIcode.ll()->testFlags(SRC_B) ? 1 : 2;
|
cb = pIcode.ll()->testFlags(SRC_B) ? 1 : 2;
|
||||||
if (cb == 1) /* uint8_t */
|
if (cb == 1) /* uint8_t */
|
||||||
{
|
{
|
||||||
pIcode.du.def |= duReg[rAX];
|
pIcode.du.def.addReg(rAX);
|
||||||
pIcode.du1.numRegsDef++;
|
pIcode.du1.numRegsDef++;
|
||||||
pIcode.du.use |= duReg[rAL];
|
pIcode.du.use.addReg(rAL);
|
||||||
}
|
}
|
||||||
else /* uint16_t */
|
else /* uint16_t */
|
||||||
{
|
{
|
||||||
pIcode.du.def |= (duReg[rDX] | duReg[rAX]);
|
pIcode.du.def.addReg(rDX).addReg(rAX);
|
||||||
pIcode.du1.numRegsDef += 2;
|
pIcode.du1.numRegsDef += 2;
|
||||||
pIcode.du.use |= duReg[rAX];
|
pIcode.du.use.addReg(rAX);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1121,7 +1121,7 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iLDS: case iLES:
|
case iLDS: case iLES:
|
||||||
pIcode.du.def |= duReg[(pIcode.ll()->getOpcode() == iLDS) ? rDS : rES];
|
pIcode.du.def.addReg(((pIcode.ll()->getOpcode() == iLDS) ? rDS : rES));
|
||||||
pIcode.du1.numRegsDef++;
|
pIcode.du1.numRegsDef++;
|
||||||
cb = 4;
|
cb = 4;
|
||||||
case iMOV:
|
case iMOV:
|
||||||
@ -1147,10 +1147,10 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case iLOOP: case iLOOPE: case iLOOPNE:
|
case iLOOP: case iLOOPE: case iLOOPNE:
|
||||||
pIcode.du.def |= duReg[rCX];
|
pIcode.du.def.addReg(rCX);
|
||||||
pIcode.du1.numRegsDef++;
|
pIcode.du1.numRegsDef++;
|
||||||
case iJCXZ:
|
case iJCXZ:
|
||||||
pIcode.du.use |= duReg[rCX];
|
pIcode.du.use.addReg(rCX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS:
|
case iREPNE_CMPS: case iREPE_CMPS: case iREP_MOVS:
|
||||||
@ -1160,22 +1160,22 @@ void Function::process_operands(ICODE & pIcode, STATE * pstate)
|
|||||||
pIcode.du.addDefinedAndUsed(rSI);
|
pIcode.du.addDefinedAndUsed(rSI);
|
||||||
pIcode.du.addDefinedAndUsed(rDI);
|
pIcode.du.addDefinedAndUsed(rDI);
|
||||||
pIcode.du1.numRegsDef += 2;
|
pIcode.du1.numRegsDef += 2;
|
||||||
pIcode.du.use |= duReg[rES] | duReg[sseg];
|
pIcode.du.use.addReg(rES).addReg(sseg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS:
|
case iREPNE_SCAS: case iREPE_SCAS: case iREP_STOS: case iREP_INS:
|
||||||
pIcode.du.addDefinedAndUsed(rCX);
|
pIcode.du.addDefinedAndUsed(rCX);
|
||||||
pIcode.du1.numRegsDef++;
|
pIcode.du1.numRegsDef++;
|
||||||
case iSCAS: case iSTOS: case iINS:
|
case iSCAS: case iSTOS: case iINS:
|
||||||
pIcode.du.def |= duReg[rDI];
|
pIcode.du.def.addReg(rDI);
|
||||||
pIcode.du1.numRegsDef++;
|
pIcode.du1.numRegsDef++;
|
||||||
if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS)
|
if (pIcode.ll()->getOpcode() == iREP_INS || pIcode.ll()->getOpcode()== iINS)
|
||||||
{
|
{
|
||||||
pIcode.du.use |= duReg[rDI] | duReg[rES] | duReg[rDX];
|
pIcode.du.use.addReg(rDI).addReg(rES).addReg(rDX);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pIcode.du.use |= duReg[rDI] | duReg[rES] | duReg[(cb == 2)? rAX: rAL];
|
pIcode.du.use.addReg(rDI).addReg(rES).addReg((cb == 2)? rAX: rAL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
********************************************************************/
|
********************************************************************/
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdint.h>
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <malloc.h> /* For free() */
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
static int numInt; /* Number of intervals */
|
static int numInt; /* Number of intervals */
|
||||||
|
|
||||||
@ -66,16 +66,16 @@ BB *interval::firstOfInt ()
|
|||||||
* node->inInterval.
|
* node->inInterval.
|
||||||
* Note: nodes are added to the interval list in interval order (which
|
* Note: nodes are added to the interval list in interval order (which
|
||||||
* topsorts the dominance relation). */
|
* topsorts the dominance relation). */
|
||||||
static void appendNodeInt (queue &pqH, BB *node, interval *pI)
|
void interval::appendNodeInt(queue &pqH, BB *node)
|
||||||
{
|
{
|
||||||
queue::iterator pq; /* Pointer to current node of the list */
|
queue::iterator pq; /* Pointer to current node of the list */
|
||||||
|
|
||||||
/* Append node if it is not already in the interval list */
|
/* Append node if it is not already in the interval list */
|
||||||
pq = appendQueue (pI->nodes, node);
|
pq = appendQueue (nodes, node);
|
||||||
|
|
||||||
/* Update currNode if necessary */
|
/* Update currNode if necessary */
|
||||||
if (pI->currNode == pI->nodes.end())
|
if (currNode == nodes.end())
|
||||||
pI->currNode = pq;
|
currNode = pq;
|
||||||
|
|
||||||
/* Check header list for occurrence of node, if found, remove it
|
/* Check header list for occurrence of node, if found, remove it
|
||||||
* and decrement number of out-edges from this interval. */
|
* and decrement number of out-edges from this interval. */
|
||||||
@ -84,12 +84,12 @@ static void appendNodeInt (queue &pqH, BB *node, interval *pI)
|
|||||||
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
auto found_iter=std::find(pqH.begin(),pqH.end(),node);
|
||||||
if(found_iter!=pqH.end())
|
if(found_iter!=pqH.end())
|
||||||
{
|
{
|
||||||
pI->numOutEdges -= (uint8_t)(*found_iter)->inEdges.size() - 1;
|
numOutEdges -= (uint8_t)(*found_iter)->inEdges.size() - 1;
|
||||||
pqH.erase(found_iter);
|
pqH.erase(found_iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Update interval header information for this basic block */
|
/* Update interval header information for this basic block */
|
||||||
node->inInterval = pI;
|
node->inInterval = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -99,11 +99,10 @@ static void appendNodeInt (queue &pqH, BB *node, interval *pI)
|
|||||||
void derSeq_Entry::findIntervals (Function *c)
|
void derSeq_Entry::findIntervals (Function *c)
|
||||||
{
|
{
|
||||||
interval *pI, /* Interval being processed */
|
interval *pI, /* Interval being processed */
|
||||||
*J; /* ^ last interval in derivedGi->Ii */
|
*J; /* ^ last interval in derivedGi->Ii */
|
||||||
BB *h, /* Node being processed */
|
BB *h, /* Node being processed */
|
||||||
*header, /* Current interval's header node */
|
*header, /* Current interval's header node */
|
||||||
*succ; /* Successor basic block */
|
*succ; /* Successor basic block */
|
||||||
//int i; /* Counter */
|
|
||||||
queue H; /* Queue of possible header nodes */
|
queue H; /* Queue of possible header nodes */
|
||||||
boolT first = true; /* First pass through the loop */
|
boolT first = true; /* First pass through the loop */
|
||||||
|
|
||||||
@ -118,8 +117,11 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
pI = new interval;
|
pI = new interval;
|
||||||
pI->numInt = (uint8_t)numInt++;
|
pI->numInt = (uint8_t)numInt++;
|
||||||
if (first) /* ^ to first interval */
|
if (first) /* ^ to first interval */
|
||||||
|
{
|
||||||
Ii = J = pI;
|
Ii = J = pI;
|
||||||
appendNodeInt (H, header, pI); /* pI(header) = {header} */
|
m_intervals.push_back(pI);
|
||||||
|
}
|
||||||
|
pI->appendNodeInt (H, header); /* pI(header) = {header} */
|
||||||
|
|
||||||
/* Process all nodes in the current interval list */
|
/* Process all nodes in the current interval list */
|
||||||
while ((h = pI->firstOfInt()) != NULL)
|
while ((h = pI->firstOfInt()) != NULL)
|
||||||
@ -134,7 +136,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
{
|
{
|
||||||
succ->reachingInt = header;
|
succ->reachingInt = header;
|
||||||
if (succ->inEdgeCount == 0)
|
if (succ->inEdgeCount == 0)
|
||||||
appendNodeInt (H, succ, pI);
|
pI->appendNodeInt (H, succ);
|
||||||
else if (! succ->beenOnH) /* out edge */
|
else if (! succ->beenOnH) /* out edge */
|
||||||
{
|
{
|
||||||
appendQueue (H, succ);
|
appendQueue (H, succ);
|
||||||
@ -148,7 +150,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */
|
if (succ->reachingInt == header || succ->inInterval == pI) /* same interval */
|
||||||
{
|
{
|
||||||
if (succ != header)
|
if (succ != header)
|
||||||
appendNodeInt (H, succ, pI);
|
pI->appendNodeInt (H, succ);
|
||||||
}
|
}
|
||||||
else /* out edge */
|
else /* out edge */
|
||||||
pI->numOutEdges++;
|
pI->numOutEdges++;
|
||||||
@ -161,6 +163,7 @@ void derSeq_Entry::findIntervals (Function *c)
|
|||||||
/* Link interval I to list of intervals */
|
/* Link interval I to list of intervals */
|
||||||
if (! first)
|
if (! first)
|
||||||
{
|
{
|
||||||
|
m_intervals.push_back(pI);
|
||||||
J->next = pI;
|
J->next = pI;
|
||||||
J = pI;
|
J = pI;
|
||||||
}
|
}
|
||||||
@ -333,13 +336,6 @@ uint8_t Function::findDerivedSeq (derSeq &derivedGi)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Converts the irreducible graph G into an equivalent reducible one, by
|
|
||||||
* means of node splitting. */
|
|
||||||
static void nodeSplitting (std::list<BB *> &/*G*/)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"Attempt to perform node splitting: NOT IMPLEMENTED\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Displays the derived sequence and intervals of the graph G */
|
/* Displays the derived sequence and intervals of the graph G */
|
||||||
void derSeq::display()
|
void derSeq::display()
|
||||||
{
|
{
|
||||||
@ -369,13 +365,13 @@ derSeq * Function::checkReducibility()
|
|||||||
stats.nOrder = 1; /* nOrder(cfg) = 1 */
|
stats.nOrder = 1; /* nOrder(cfg) = 1 */
|
||||||
der_seq = new derSeq;
|
der_seq = new derSeq;
|
||||||
der_seq->resize(1);
|
der_seq->resize(1);
|
||||||
der_seq->back().Gi = m_cfg.front();
|
der_seq->back().Gi = *m_actual_cfg.begin(); /*m_cfg.front()*/;
|
||||||
reducible = findDerivedSeq(*der_seq);
|
reducible = findDerivedSeq(*der_seq);
|
||||||
|
|
||||||
if (! reducible)
|
if (! reducible)
|
||||||
{
|
{
|
||||||
flg |= GRAPH_IRRED;
|
flg |= GRAPH_IRRED;
|
||||||
nodeSplitting (m_cfg);
|
m_actual_cfg.nodeSplitting();
|
||||||
}
|
}
|
||||||
return der_seq;
|
return der_seq;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
#define TABLESIZE 16 /* Number of entries added each expansion */
|
#define TABLESIZE 16 /* Number of entries added each expansion */
|
||||||
/* Probably has to be a power of 2 */
|
/* Probably has to be a power of 2 */
|
||||||
#define STRTABSIZE 256 /* Size string table is inc'd by */
|
#define STRTABSIZE 256 /* Size string table is inc'd by */
|
||||||
#define NIL ((uint16_t)-1)
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
static char *pStrTab; /* Pointer to the current string table */
|
static char *pStrTab; /* Pointer to the current string table */
|
||||||
static int strTabNext; /* Next free index into pStrTab */
|
static int strTabNext; /* Next free index into pStrTab */
|
||||||
|
|||||||
@ -60,7 +60,8 @@ void Function::controlFlowAnalysis()
|
|||||||
if (option.verbose)
|
if (option.verbose)
|
||||||
{
|
{
|
||||||
printf("\nDepth first traversal - Proc %s\n", name.c_str());
|
printf("\nDepth first traversal - Proc %s\n", name.c_str());
|
||||||
m_cfg.front()->displayDfs();
|
(*m_actual_cfg.begin())->displayDfs();
|
||||||
|
//m_cfg.front()->displayDfs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free storage occupied by this procedure */
|
/* Free storage occupied by this procedure */
|
||||||
@ -82,7 +83,7 @@ void udm(void)
|
|||||||
/* Data flow analysis - eliminate condition codes, extraneous registers
|
/* Data flow analysis - eliminate condition codes, extraneous registers
|
||||||
* and intermediate instructions. Find expressions by forward
|
* and intermediate instructions. Find expressions by forward
|
||||||
* substitution algorithm */
|
* substitution algorithm */
|
||||||
std::bitset<32> live_regs;
|
LivenessSet live_regs;
|
||||||
Project::get()->pProcList.front().dataFlow (live_regs);
|
Project::get()->pProcList.front().dataFlow (live_regs);
|
||||||
|
|
||||||
/* Control flow analysis - structuring algorithm */
|
/* Control flow analysis - structuring algorithm */
|
||||||
@ -98,7 +99,7 @@ void udm(void)
|
|||||||
void Function::displayCFG()
|
void Function::displayCFG()
|
||||||
{
|
{
|
||||||
printf("\nBasic Block List - Proc %s", name.c_str());
|
printf("\nBasic Block List - Proc %s", name.c_str());
|
||||||
for (BB *pBB : m_cfg)
|
for (BB *pBB : /*m_cfg*/m_actual_cfg)
|
||||||
{
|
{
|
||||||
pBB->display();
|
pBB->display();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,4 +3,4 @@ cd bld
|
|||||||
make -j5
|
make -j5
|
||||||
cd ..
|
cd ..
|
||||||
./test_use_base.sh
|
./test_use_base.sh
|
||||||
./valgrind_tester ./bld/dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
./valgrind_tester ./dcc_original -s -c 2>stderr >stdout; diff tests/prev/ tests/outputs/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user