This commit is contained in:
Artur K
2012-07-20 18:18:25 +02:00
parent f6118dc0c4
commit 0209b7ceb2
28 changed files with 1028 additions and 768 deletions

View File

@@ -36,7 +36,7 @@ private:
numHlIcodes(0),flg(0),
inEdges(0),
edges(0),beenOnH(0),inEdgeCount(0),reachingInt(0),
inInterval(0),correspInt(0),liveUse(0),def(0),liveIn(0),liveOut(0),
inInterval(0),correspInt(0),
dfsFirstNum(0),dfsLastNum(0),immedDom(0),ifFollow(0),loopType(0),latchNode(0),
numBackEdges(0),loopHead(0),loopFollow(0),caseHead(0),caseTail(0),index(0)
{

View File

@@ -143,7 +143,7 @@ public:
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)
hasCase(false),liveAnal(0)//,next(0),prev(0)
{
}
public:

View File

@@ -59,12 +59,8 @@ typedef struct { /* Command line option flags */
extern OPTION option; /* Command line options */
#include "BinaryImage.h"
extern LivenessSet duReg[30]; /* def/use bits for registers */
//extern uint32_t duReg[30]; /* def/use bits for registers */
extern LivenessSet maskDuReg[30]; /* masks off du bits for regs */
/* Registers used by icode instructions */
/* Memory map states */
enum eAreaType
@@ -130,8 +126,8 @@ char *writeJcondInv (HLTYPE, Function *, int *);
/* Exported funcions from locident.c */
boolT checkLongEq (LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
boolT checkLongRegEq (LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
bool checkLongEq(LONG_STKID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &atOffset);
bool checkLongRegEq(LONGID_TYPE, iICODE, int, Function *, Assignment &asgn, LLInst &);
eReg otherLongRegi(eReg, int, LOCAL_ID *);

View File

@@ -7,6 +7,9 @@
#include <vector>
#include <list>
#include <bitset>
#include <set>
#include <algorithm>
#include <initializer_list>
#include <llvm/ADT/ilist.h>
#include <llvm/ADT/ilist_node.h>
#include <llvm/MC/MCInst.h>
@@ -29,21 +32,24 @@ typedef std::list<ICODE>::iterator iICODE;
typedef std::list<ICODE>::reverse_iterator riICODE;
typedef boost::iterator_range<iICODE> rCODE;
struct LivenessSet : public std::bitset<32>
struct LivenessSet
{
LivenessSet(int val=0) : std::bitset<32>(val) {}
LivenessSet(const LivenessSet &other)
std::set<eReg> registers;
public:
LivenessSet(const std::initializer_list<eReg> &init) : registers(init) {}
LivenessSet() {}
LivenessSet(const LivenessSet &other) : registers(other.registers)
{
(std::bitset<32> &)*this = (std::bitset<32> &)other;
}
LivenessSet(const std::bitset<32> &other)
void reset()
{
(std::bitset<32> &)*this = other;
registers.clear();
}
// LivenessSet(LivenessSet &&other) : LivenessSet()
// {
// swap(*this,other);
// }
// LivenessSet(LivenessSet &&other) : LivenessSet()
// {
// swap(*this,other);
// }
LivenessSet &operator=(LivenessSet other)
{
swap(*this,other);
@@ -56,22 +62,65 @@ struct LivenessSet : public std::bitset<32>
// by swapping the members of two classes,
// the two classes are effectively swapped
swap((std::bitset<32> &)first, (std::bitset<32> &)second);
swap(first.registers, second.registers);
}
LivenessSet &operator|=(const LivenessSet &other)
{
registers.insert(other.registers.begin(),other.registers.end());
return *this;
}
LivenessSet &operator&=(const LivenessSet &other)
{
std::set<eReg> res;
std::set_intersection(registers.begin(),registers.end(),
other.registers.begin(),other.registers.end(),
std::inserter(res, res.end()));
registers = res;
return *this;
}
LivenessSet &operator-=(const LivenessSet &other)
{
std::set<eReg> res;
std::set_difference(registers.begin(),registers.end(),
other.registers.begin(),other.registers.end(),
std::inserter(res, res.end()));
registers = res;
return *this;
}
LivenessSet operator-(const LivenessSet &other) const
{
return LivenessSet(*this) -= other;
}
LivenessSet operator+(const LivenessSet &other) const
{
return LivenessSet(*this) |= other;
}
LivenessSet operator &(const LivenessSet &other) const
{
return LivenessSet(*this) &= other;
}
bool any() const
{
return not registers.empty();
}
bool operator==(const LivenessSet &other) const
{
return registers==other.registers;
}
bool operator!=(const LivenessSet &other) const { return not(*this==other);}
LivenessSet &setReg(int r);
LivenessSet &addReg(int r);
bool testReg(int r)
bool testReg(int r) const
{
return test(r-rAX);
return registers.find(eReg(r))!=registers.end();
}
public:
bool testRegAndSubregs(int r) const;
LivenessSet &clrReg(int r);
private:
void postProcessCompositeRegs();
};
extern LivenessSet duReg[30];
/* uint8_t and uint16_t registers */
/* Def/use of flags - low 4 bits represent flags */
@@ -180,8 +229,8 @@ public:
void setCall(Function *proc);
HLTYPE(hlIcode op=HLI_INVALID) : opcode(op)
{}
// HLTYPE() // help valgrind find uninitialized HLTYPES
// {}
// HLTYPE() // help valgrind find uninitialized HLTYPES
// {}
HLTYPE & operator=(const HLTYPE &l)
{
exp = l.exp;
@@ -197,7 +246,6 @@ public:
/* LOW_LEVEL icode operand record */
struct LLOperand
{
llvm::MCOperand llvm_op;
eReg seg; /* CS, DS, ES, SS */
eReg segOver; /* CS, DS, ES, SS if segment override */
int16_t segValue; /* Value of segment seg during analysis */
@@ -245,6 +293,10 @@ struct LLOperand
Op.regi = (eReg)Val;
return Op;
}
bool isSet()
{
return not (*this == LLOperand());
}
void addProcInformation(int param_count,uint32_t call_conv);
};
struct LLInst : public llvm::MCInst //: public llvm::ilist_node<LLInst>
@@ -256,7 +308,7 @@ public:
int codeIdx; /* Index into cCode.code */
uint8_t numBytes; /* Number of bytes this instr */
uint32_t label; /* offset in image (20-bit adr) */
LLOperand dst; /* destination operand */
LLOperand m_dst; /* destination operand */
DU flagDU; /* def/use of flags */
int caseEntry;
std::vector<uint32_t> caseTbl2;
@@ -285,25 +337,29 @@ public:
{
return (getOpcode()==op);
}
bool matchWithRegDst(llIcode op)
{
return (getOpcode()==op) and m_dst.isReg();
}
bool match(llIcode op,eReg dest)
{
return (getOpcode()==op)&&dst.regi==dest;
return (getOpcode()==op)&&m_dst.regi==dest;
}
bool match(llIcode op,eReg dest,uint32_t flgs)
{
return (getOpcode()==op) and (dst.regi==dest) and testFlags(flgs);
return (getOpcode()==op) and (m_dst.regi==dest) and testFlags(flgs);
}
bool match(llIcode op,eReg dest,eReg src_reg)
{
return (getOpcode()==op)&&(dst.regi==dest)&&(m_src.regi==src_reg);
return (getOpcode()==op)&&(m_dst.regi==dest)&&(m_src.regi==src_reg);
}
bool match(eReg dest,eReg src_reg)
{
return (dst.regi==dest)&&(m_src.regi==src_reg);
return (m_dst.regi==dest)&&(m_src.regi==src_reg);
}
bool match(eReg dest)
{
return (dst.regi==dest);
return (m_dst.regi==dest);
}
bool match(llIcode op,uint32_t flgs)
{
@@ -314,6 +370,19 @@ public:
setOpcode(op);
flg =flags;
}
void set(llIcode op,uint32_t flags,eReg dst_reg)
{
setOpcode(op);
m_dst = LLOperand::CreateReg2(dst_reg);
flg =flags;
}
void set(llIcode op,uint32_t flags,eReg dst_reg,const LLOperand &src_op)
{
setOpcode(op);
m_dst = LLOperand::CreateReg2(dst_reg);
m_src = src_op;
flg =flags;
}
void emitGotoLabel(int indLevel);
void findJumpTargets(CIcodeRec &_pc);
void writeIntComment(std::ostringstream &s);
@@ -343,16 +412,16 @@ public:
}
void replaceDst(const LLOperand &with)
{
dst = with;
}
void replaceDst(eReg r)
{
dst = LLOperand::CreateReg2(r);
m_dst = with;
}
// void replaceDst(eReg r)
// {
// dst = LLOperand::CreateReg2(r);
// }
ICODE *m_link;
condId idType(opLoc sd) const;
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &dst; }
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &dst; }
const LLOperand * get(opLoc sd) const { return (sd == SRC) ? &src() : &m_dst; }
LLOperand * get(opLoc sd) { return (sd == SRC) ? &src() : &m_dst; }
};
/* Icode definition: LOW_LEVEL and HIGH_LEVEL */
@@ -407,6 +476,10 @@ public:
};
struct DU1
{
protected:
int numRegsDef; /* # registers defined by this inst */
public:
struct Use
{
int Reg; // used register
@@ -422,7 +495,6 @@ public:
}
};
int numRegsDef; /* # registers defined by this inst */
uint8_t regi[MAX_REGS_DEF+1]; /* registers defined by this inst */
Use idx[MAX_REGS_DEF+1];
//int idx[MAX_REGS_DEF][MAX_USES]; /* inst that uses this def */
@@ -447,6 +519,11 @@ public:
Use &u(idx[regIdx]);
u.removeUser(ic);
}
int getNumRegsDef() const {return numRegsDef;}
void clearAllDefs() {numRegsDef=0;}
DU1 &addDef(eReg r) {numRegsDef++; return *this;}
DU1 &setDef(eReg r) {numRegsDef=1; return *this;}
void removeDef(eReg r) {numRegsDef--;}
DU1() : numRegsDef(0)
{
}
@@ -460,13 +537,13 @@ public:
const LLInst * ll() const { return &m_ll;}
HLTYPE * hlU() {
// assert(type==HIGH_LEVEL);
// assert(m_hl.opcode!=HLI_INVALID);
// assert(type==HIGH_LEVEL);
// assert(m_hl.opcode!=HLI_INVALID);
return &m_hl;
}
const HLTYPE * hl() const {
// assert(type==HIGH_LEVEL);
// assert(m_hl.opcode!=HLI_INVALID);
// assert(type==HIGH_LEVEL);
// assert(m_hl.opcode!=HLI_INVALID);
return &m_hl;
}
void hl(const HLTYPE &v) { m_hl=v;}
@@ -501,9 +578,9 @@ public:
{
}
public:
const MachineBasicBlock* getParent() const { return Parent; }
MachineBasicBlock* getParent() { return Parent; }
//unsigned getNumOperands() const { return (unsigned)Operands.size(); }
const MachineBasicBlock* getParent() const { return Parent; }
MachineBasicBlock* getParent() { return Parent; }
//unsigned getNumOperands() const { return (unsigned)Operands.size(); }
};
/** Map n low level instructions to m high level instructions

View File

@@ -31,37 +31,67 @@ struct IDX_ARRAY : public std::vector<iICODE>
}
};
typedef enum
enum frameType
{
STK_FRAME, /* For stack vars */
REG_FRAME, /* For register variables */
GLB_FRAME /* For globals */
} frameType;
};
typedef struct
struct BWGLB_TYPE
{
int16_t seg; /* segment value */
int16_t off; /* offset */
eReg regi; /* optional indexed register */
} BWGLB_TYPE;
} ;
typedef struct
{ /* For TYPE_LONG_(UN)SIGN on the stack */
/* For TYPE_LONG_(UN)SIGN on the stack */
struct LONG_STKID_TYPE
{
int offH; /* high offset from BP */
int offL; /* low offset from BP */
} LONG_STKID_TYPE;
LONG_STKID_TYPE(int h,int l) : offH(h),offL(l) {}
};
/* For TYPE_LONG_(UN)SIGN registers */
struct LONGID_TYPE
{ /* For TYPE_LONG_(UN)SIGN registers */
eReg h; /* high register */
eReg l; /* low register */
{
protected:
eReg m_h; /* high register */
eReg m_l; /* low register */
public:
void set(eReg highpart,eReg lowpart)
{
m_h = highpart;
m_l = lowpart;
}
eReg l() const { return m_l; }
eReg h() const { return m_h; }
bool srcDstRegMatch(iICODE a,iICODE b) const;
LONGID_TYPE() {} // uninitializing constructor to help valgrind catch uninit accesses
LONGID_TYPE(eReg h,eReg l) : m_h(h),m_l(l) {}
};
struct LONGGLB_TYPE /* For TYPE_LONG_(UN)SIGN globals */
{
int16_t seg; /* segment value */
int16_t offH; /* offset high */
int16_t offL; /* offset low */
uint8_t regi; /* optional indexed register */
LONGGLB_TYPE(int16_t _seg,int16_t _H,int16_t _L,int8_t _reg=0)
{
seg=_seg;
offH=_H;
offL=_L;
regi=_reg;
}
};
/* ID, LOCAL_ID */
struct ID
{
protected:
LONGID_TYPE m_longId; /* For TYPE_LONG_(UN)SIGN registers */
public:
hlType type; /* Probable type */
bool illegal; /* Boolean: not a valid field any more */
//std::vector<iICODE> idx;
@@ -70,33 +100,39 @@ struct ID
bool hasMacro; /* Identifier requires a macro */
char macro[10]; /* Macro for this identifier */
std::string name; /* Identifier's name */
union { /* Different types of identifiers */
union ID_UNION { /* Different types of identifiers */
friend class ID;
protected:
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
public:
eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
uint8_t regOff; /* register offset (if any) */
int off; /* offset from BP */
} bwId;
BWGLB_TYPE bwGlb; /* For TYPE_BYTE(uint16_t)_(UN)SIGN globals */
LONGID_TYPE longId; /* For TYPE_LONG_(UN)SIGN registers */
LONG_STKID_TYPE longStkId; /* For TYPE_LONG_(UN)SIGN on the stack */
struct { /* For TYPE_LONG_(UN)SIGN globals */
int16_t seg; /* segment value */
int16_t offH; /* offset high */
int16_t offL; /* offset low */
uint8_t regi; /* optional indexed register */
} longGlb;
LONGGLB_TYPE longGlb;
struct { /* For TYPE_LONG_(UN)SIGN constants */
uint32_t h; /* high uint16_t */
uint32_t l; /* low uint16_t */
} longKte;
ID_UNION() { /*new (&longStkId) LONG_STKID_TYPE();*/}
} id;
LONGID_TYPE &longId() {assert(isLong() && loc==REG_FRAME); return m_longId;}
const LONGID_TYPE &longId() const {assert(isLong() && loc==REG_FRAME); return m_longId;}
LONG_STKID_TYPE &longStkId() {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
const LONG_STKID_TYPE &longStkId() const {assert(isLong() && loc==STK_FRAME); return id.longStkId;}
ID();
ID(hlType t, frameType f);
ID(hlType t, const LONGID_TYPE &s);
ID(hlType t, const LONG_STKID_TYPE &s);
ID(hlType t, const LONGGLB_TYPE &s);
bool isSigned() const { return (type==TYPE_BYTE_SIGN)||(type==TYPE_WORD_SIGN)||(type==TYPE_LONG_SIGN);}
uint16_t typeBitsize() const
{
return TypeContainer::typeSize(type)*8;
}
bool isLong() const { return (type==TYPE_LONG_UNSIGN)||(type==TYPE_LONG_SIGN); }
void setLocalName(int i)
{
char buf[32];
@@ -123,7 +159,7 @@ public:
int newByteWordReg(hlType t, eReg regi);
int newByteWordStk(hlType t, int off, uint8_t regOff);
int newIntIdx(int16_t seg, int16_t off, eReg regi, hlType t);
int newLongReg(hlType t, eReg regH, eReg regL, iICODE ix_);
int newLongReg(hlType t, const LONGID_TYPE &longT, iICODE ix_);
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, int off);
int newLong(opLoc sd, iICODE pIcode, hlFirst f, iICODE ix, operDu du, LLInst &atOffset);
void newIdent(hlType t, frameType f);

View File

@@ -4,6 +4,7 @@
#include <sstream>
#include <bitset>
struct LivenessSet;
/* Machine registers */
enum eReg
{
@@ -32,8 +33,9 @@ enum eReg
rBH = 20,
rTMP= 21, /* temp register for DIV/IDIV/MOD */
rTMP2= 22, /* temp register for DIV/IDIV/MOD */
/* Indexed modes go from INDEXBASE to INDEXBASE+7 */
INDEX_BX_SI = 22, // "bx+si"
INDEX_BX_SI = 23, // "bx+si"
INDEX_BX_DI, // "bx+di"
INDEX_BP_SI, // "bp+si"
INDEX_BP_DI, // "bp+di"
@@ -64,15 +66,7 @@ public:
bool physicalReg(eReg r);
/* Writes the registers that are set in the bitvector */
//TODO: move this into Machine_X86 ?
static void writeRegVector (std::ostream &ostr,const std::bitset<32> &regi)
{
int j;
for (j = rAX; j < INDEX_BX_SI; j++)
{
if (regi.test(j-1))
ostr << regName(eReg(j))<<" ";
}
}
static void writeRegVector (std::ostream &ostr,const LivenessSet &regi);
static eReg subRegH(eReg reg);
static eReg subRegL(eReg reg);
static bool isMemOff(eReg r);