diff options
Diffstat (limited to 'includes/compiler')
53 files changed, 1365 insertions, 53 deletions
diff --git a/includes/compiler/AddPropagation.h b/includes/compiler/AddPropagation.h index 1f4b94a..11732a9 100644 --- a/includes/compiler/AddPropagation.h +++ b/includes/compiler/AddPropagation.h @@ -3,4 +3,8 @@ #include "compiler/common.h" +extern int propagatedadds; + +extern void propagateaddinstructions(Object *proc); + #endif diff --git a/includes/compiler/Alias.h b/includes/compiler/Alias.h index 39f7220..08dbb00 100644 --- a/includes/compiler/Alias.h +++ b/includes/compiler/Alias.h @@ -3,4 +3,57 @@ #include "compiler/common.h" +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct AliasMember AliasMember; + +typedef enum AliasType { + AliasType0, + AliasType1, + AliasType2 +} AliasType; + +struct Alias { + Alias *next; + Alias *hashNext; + AliasMember *children; + AliasMember *parents; + Object *object; + SInt32 offset; + SInt32 size; + int valuenumber; + PCode *valuepcode; + UInt32 *vec24; + int index; + AliasType type; +}; + +struct AliasMember { + AliasMember *nextParent; + AliasMember *nextChild; + Alias *parent; + Alias *child; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern Alias *worst_case; +extern Object worst_case_obj; + +extern void initialize_aliases(void); +extern Alias *make_alias(Object *object, SInt32 offset, SInt32 size); +extern Alias *make_alias_set(void); +extern void add_alias_member(Alias *parent, Alias *child); +extern Alias *make_alias_set_from_IR(void); +extern void gather_alias_info(void); +extern Boolean may_alias(PCode *a, PCode *b); +extern Boolean uniquely_aliases(PCode *a, PCode *b); +extern Boolean may_alias_worst_case(PCode *pcode); +extern Boolean may_alias_object(PCode *pcode, Object *object); +extern void initialize_alias_values(void); +extern void update_alias_value(Alias *alias, PCode *pcode); +extern void update_all_alias_values(void); + #endif diff --git a/includes/compiler/IroBitVect.h b/includes/compiler/BitVector.h index 7bbca22..f8f8143 100644 --- a/includes/compiler/IroBitVect.h +++ b/includes/compiler/BitVector.h @@ -25,11 +25,13 @@ extern Boolean Bv_IsEmpty(const BitVector *bv); inline void Bv_SetBit(UInt32 bit, BitVector *bv) { if ((bit / 32) < bv->size) { - bv->data[bit / 32] |= ~(1 << (bit & 31)); + bv->data[bit / 32] |= 1 << (bit & 31); } else { #line 56 CError_FATAL(); } } +#define Bv_IsBitSet(_bit, _bv) ( (((_bit) >> 5) < (_bv)->size) && ((_bv)->data[(_bit) >> 5] & (1 << ((_bit) & 31))) ) + #endif diff --git a/includes/compiler/BitVectors.h b/includes/compiler/BitVectors.h index 7849dcb..068fec0 100644 --- a/includes/compiler/BitVectors.h +++ b/includes/compiler/BitVectors.h @@ -3,4 +3,19 @@ #include "compiler/common.h" +extern void bitvectorcopy(UInt32 *dst, UInt32 *src, int len); +extern int bitvectorchanged(UInt32 *dst, UInt32 *src, int len); +extern void bitvectorinitialize(UInt32 *vec, int len, UInt32 initval); +extern void bitvectorintersect(UInt32 *dst, UInt32 *src, int len); +extern void bitvectorunion(UInt32 *dst, UInt32 *src, int len); +extern void bitvectordifference(UInt32 *dst, UInt32 *src, int len); +extern void bitvectorcomplement(UInt32 *dst, UInt32 *src, int len); +extern int bitvectorcount(UInt32 *vec, int len); +extern int bitvectorisempty(UInt32 *vec, int len); +extern int bitvectorintersectionisempty(UInt32 *a, UInt32 *b, int len); + +#define bitvectorgetbit(_bit, _vec) ((1 << ((_bit) & 31)) & (_vec)[(_bit) >> 5]) +#define bitvectorsetbit(_bit, _vec) ((_vec)[(_bit) >> 5] |= 1 << ((_bit) & 31)) +#define bitvectorclearbit(_bit, _vec) ((_vec)[(_bit) >> 5] &= ~(1 << ((_bit) & 31))) + #endif diff --git a/includes/compiler/CException.h b/includes/compiler/CException.h index 0a4d60d..04af4fa 100644 --- a/includes/compiler/CException.h +++ b/includes/compiler/CException.h @@ -3,4 +3,7 @@ #include "compiler/common.h" +// TODO +extern Boolean CExcept_CanThrowException(Object *obj, Boolean flag); + #endif diff --git a/includes/compiler/CInt64.h b/includes/compiler/CInt64.h index 7986a4a..dc8b51d 100644 --- a/includes/compiler/CInt64.h +++ b/includes/compiler/CInt64.h @@ -10,7 +10,7 @@ extern const CInt64 cint64_one; extern const CInt64 cint64_max; extern const CInt64 cint64_min; -inline int CInt64_IsNegative(const CInt64 *n) { +inline Boolean CInt64_IsNegative(const CInt64 *n) { return (n->hi & 0x80000000) != 0; } inline UInt32 CInt64_GetULong(const CInt64 *n) { // 42E660 in mwcppc.exe @@ -33,6 +33,9 @@ inline Boolean CInt64_IsZero(CInt64 *n) { // return 0; return n->hi == 0 && n->lo == 0; } +inline Boolean CInt64_IsOne(CInt64 *n) { // assumed name + return n->hi == 0 && n->lo == 1; +} inline void CInt64_Extend32(CInt64 *n) { // assumed name n->hi = (n->lo >> 31) ? 0xFFFFFFFF : 0; } diff --git a/includes/compiler/CParser.h b/includes/compiler/CParser.h index 4eb1abb..ee49869 100644 --- a/includes/compiler/CParser.h +++ b/includes/compiler/CParser.h @@ -71,7 +71,7 @@ typedef struct COpts { Boolean disable_registers; Boolean fp_contract; Boolean no_register_save_helpers; - char ppc_unroll_speculative; + Boolean ppc_unroll_speculative; short ppc_unroll_instructions_limit; short ppc_unroll_factor_limit; Boolean altivec_model; @@ -206,20 +206,20 @@ typedef struct COpts { Boolean optimize_for_size; Boolean optimizewithasm; Boolean crippled; - char opt_common_subs; - char opt_loop_invariants; + Boolean opt_common_subs; + Boolean opt_loop_invariants; char opt_propagation; char opt_dead_assignments; - char opt_strength_reduction; - char opt_strength_reduction_strict; + Boolean opt_strength_reduction; + Boolean opt_strength_reduction_strict; char opt_dead_code; char opt_lifetimes; char _B1; // unused? char opt_unroll_loops; char opt_vectorize_loops; char _B4; // amount of IRO passes? - char opt_pointer_analysis; - char opt_pointer_analysis_mode; + Boolean opt_pointer_analysis; + unsigned char opt_pointer_analysis_mode; char loop_unroll_count; char loop_unroll_size_threshold; Boolean isGeneratingDebugInfo; diff --git a/includes/compiler/CodeMotion.h b/includes/compiler/CodeMotion.h index 5d25726..f655cb8 100644 --- a/includes/compiler/CodeMotion.h +++ b/includes/compiler/CodeMotion.h @@ -3,4 +3,9 @@ #include "compiler/common.h" +extern int movedloopinvariantcode; +extern int unswitchedinvariantcode; + +extern void moveloopinvariantcode(void); + #endif diff --git a/includes/compiler/Coloring.h b/includes/compiler/Coloring.h index 85bacf6..a84d5ee 100644 --- a/includes/compiler/Coloring.h +++ b/includes/compiler/Coloring.h @@ -2,5 +2,11 @@ #define COMPILER_COLORING_H #include "compiler/common.h" +#include "compiler/Registers.h" + +//extern RegClass coloring_class; +extern char coloring_class; + +extern void colorinstructions(Object *proc); #endif diff --git a/includes/compiler/CompilerTools.h b/includes/compiler/CompilerTools.h index 50581b0..dbaf7d9 100644 --- a/includes/compiler/CompilerTools.h +++ b/includes/compiler/CompilerTools.h @@ -119,6 +119,12 @@ extern void memclr(void *ptr, SInt32 size); extern void memclrw(void *ptr, SInt32 size); extern void CToLowercase(char *a, char *b); extern short getbit(SInt32 l); +extern inline SInt32 CTool_EndianReadWord32(void *value) { + return *((SInt32 *) value); +} +extern inline UInt32 CTool_EndianConvertWord32(UInt32 value) { + return value; +} extern void CTool_EndianConvertWord64(CInt64 ci, char *result); extern UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x); extern UInt32 CTool_EndianConvertInPlaceWord32Ptr(UInt32 *x); diff --git a/includes/compiler/ConstantPropagation.h b/includes/compiler/ConstantPropagation.h index 4b702ee..ed4d833 100644 --- a/includes/compiler/ConstantPropagation.h +++ b/includes/compiler/ConstantPropagation.h @@ -3,4 +3,8 @@ #include "compiler/common.h" +extern int propagatedconstants; + +extern void propagateconstants(void); + #endif diff --git a/includes/compiler/CopyPropagation.h b/includes/compiler/CopyPropagation.h index 841f8dc..8d80067 100644 --- a/includes/compiler/CopyPropagation.h +++ b/includes/compiler/CopyPropagation.h @@ -2,5 +2,51 @@ #define COMPILER_COPYPROPAGATION_H #include "compiler/common.h" +#include "compiler/UseDefChains.h" + +typedef int (*IsCandidateFunc)(PCode *); +typedef int (*PropagatesToUseFunc)(int a, int b); +typedef void (*PropagateAndFinishFunc)(int id); + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct Propagation { + IsCandidateFunc is_candidate; + PropagatesToUseFunc propagatestouse; + PropagateAndFinishFunc propagateandfinish; + char *name; + char *nameplural; + char *format; + Boolean computesUseDefChains; +} Propagation; + +typedef struct Candidate { + PCode *pcode; + RegUseOrDef *list; +} Candidate; + +typedef struct PropInfo { + UInt32 *vec0; + UInt32 *vec4; + UInt32 *vec8; + UInt32 *vecC; +} PropInfo; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern int propagatedcopies; +extern int propagated_instructions; +extern int recursive_propagation; +extern int number_of_candidates; +extern Candidate *Candidates; +extern PropInfo *propinfo; +extern int *ncandidatesinblock; +extern int *firstcandidateinblock; + +extern int precedes(PCode *a, PCode *b); +extern void propagateinstructions(Object *proc, Propagation *config, int passCount, Boolean localflag); +extern void propagatecopyinstructions(Object *proc, int flag); #endif diff --git a/includes/compiler/IROUseDef.h b/includes/compiler/IROUseDef.h index 5a13581..829a396 100644 --- a/includes/compiler/IROUseDef.h +++ b/includes/compiler/IROUseDef.h @@ -1,6 +1,48 @@ #ifndef COMPILER_IROUSEDEF_H #define COMPILER_IROUSEDEF_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/BitVector.h" +#include "compiler/enode.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +struct IROUse { + SInt32 index; + IRONode *node; + IROLinear *linear; + VarRecord *var; + IROUse *globalnext; + IROUse *varnext; + BitVector *x18; + UInt16 x1C; +}; +struct IRODef { + SInt32 index; + IRONode *node; + IROLinear *linear; + VarRecord *var; + IRODef *globalnext; + IRODef *varnext; + UInt16 x18; + Boolean x1A; + Boolean x1B; + Boolean x1C; + Boolean x1D; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern ENodeType IRO_NonAssignmentOp[MAXEXPR]; +extern IROUse *IRO_FirstVarUse; +extern IROUse *IRO_LastVarUse; + +extern CInt64 IRO_GetSelfAssignmentVal(IROLinear *linear); +extern void IRO_InitializeNonAssignmentOpArray(void); +extern void IRO_InitializeAssignmentFoldingFunctionArray(void); +extern Boolean IRO_UseDef(Boolean optDeadAssignments, Boolean optPropagation); +extern void IRO_SplitLifetimes(void); #endif diff --git a/includes/compiler/InlineAsm.h b/includes/compiler/InlineAsm.h index aadbc1f..b3b201b 100644 --- a/includes/compiler/InlineAsm.h +++ b/includes/compiler/InlineAsm.h @@ -150,7 +150,8 @@ typedef enum IAEffectType { IAEffect_0, IAEffect_1, IAEffect_2, - IAEffect_3 + IAEffect_3, + IAEffect_4 } IAEffectType; typedef struct IAEffect { IAEffectType type; @@ -166,8 +167,8 @@ typedef struct IAEffects { Boolean x3; Boolean x4; Boolean x5; - UInt32 numoperands; - UInt32 numlabels; + SInt32 numoperands; + SInt32 numlabels; IAEffect operands[16]; CLabel *labels[16]; } IAEffects; diff --git a/includes/compiler/InterferenceGraph.h b/includes/compiler/InterferenceGraph.h index 588450c..8fa44a1 100644 --- a/includes/compiler/InterferenceGraph.h +++ b/includes/compiler/InterferenceGraph.h @@ -3,4 +3,39 @@ #include "compiler/common.h" +enum { + fSpilled = 1, + fPushed = 2, + fCoalesced = 4, + fCoalescedInto = 8, + fPairHigh = 0x10, + fPairLow = 0x20, + fIGNode40 = 0x40 +}; + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct IGNode { + struct IGNode *next; + Object *spillTemporary; + PCode *instr8; + int spillCost; + short x10; + short x12; + short x14; + UInt16 flags; + short arraySize; + short array[1]; +} IGNode; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern IGNode **interferencegraph; +extern Boolean coalesced_nregisters; + +extern int interferes(UInt32 a, UInt32 b); +extern void buildinterferencegraph(Object *proc); + #endif diff --git a/includes/compiler/IrOptimizer.h b/includes/compiler/IrOptimizer.h index ef86286..2061a5d 100644 --- a/includes/compiler/IrOptimizer.h +++ b/includes/compiler/IrOptimizer.h @@ -3,7 +3,28 @@ #include "compiler/common.h" -// do me +typedef struct IROAddrRecord IROAddrRecord; +typedef struct IROAssign IROAssign; +typedef struct IRODef IRODef; +typedef struct IROElmList IROElmList; +typedef struct IROExpr IROExpr; +typedef struct IROLinear IROLinear; +typedef struct IROList IROList; +typedef struct IROListNode IROListNode; +typedef struct IROLoop IROLoop; +typedef struct IRONode IRONode; +typedef struct IROUse IROUse; + +extern Boolean DoScalarize; +extern Boolean DoLinearize; +extern Boolean EarlyReturn; +extern Boolean IRO_CPFirstTime; +extern Boolean VectorPhaseCalledFromUnroll; +extern Boolean IRO_Log; + extern Statement *IRO_Optimizer(Object *obj, Statement *stmt); +extern void IRO_Setup(void); +extern void IRO_Cleanup(void); +extern void CodeGen_UpdateOptimizerOptions(void); #endif diff --git a/includes/compiler/IroCSE.h b/includes/compiler/IroCSE.h index 2030e5b..4bf127c 100644 --- a/includes/compiler/IroCSE.h +++ b/includes/compiler/IroCSE.h @@ -1,6 +1,45 @@ #ifndef COMPILER_IROCSE_H #define COMPILER_IROCSE_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/BitVector.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +struct IROExpr { + Boolean x0; + UInt16 index; + IROLinear *linear; + Object *x8; + IRONode *node; + BitVector *depends; + IROExpr *x14; + Boolean couldError; + Boolean notSubable; + IROLinear *x1A; + VarRecord *x1E; + IROLinear *x22; + IROExpr *next; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern BitVector *IRO_Depends; +extern Boolean IRO_NotSubable; +extern Boolean IRO_IsVolatile; +extern Boolean IRO_CouldError; +extern IROExpr *IRO_FirstExpr; +extern IROExpr *IRO_LastExpr; +extern SInt32 IRO_NumExprs; + +extern void IRO_FindDepends_NoAlloc(IROLinear *linear); +extern void IRO_FindDepends(IROLinear *linear); +extern void IRO_FindExpressions(BitVector *bv, Boolean flag); +extern void IRO_RemoveExpr(IROExpr *expr); +extern void IRO_ComputeAvail(void); +extern void IRO_CommonSubs(void); +extern void IRO_GenerateTopLevelExprsForSubableOperands(void); #endif diff --git a/includes/compiler/IroDump.h b/includes/compiler/IroDump.h index a2f74ff..5445280 100644 --- a/includes/compiler/IroDump.h +++ b/includes/compiler/IroDump.h @@ -1,6 +1,27 @@ #ifndef COMPILER_IRODUMP_H #define COMPILER_IRODUMP_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/BitVector.h" +#include "compiler/enode.h" + +extern char *IRO_NodeName(ENodeType nodetype); +extern void IRO_InitializeNodeNamesArray(void); +extern void IRO_DumpIntTree(IROLinear *linear); +extern void IRO_DumpLinearList(IROLinear *linear); +extern void IRO_DumpBits(char *name, BitVector *bv); +extern void IRO_DumpAfterPhase(char *str, Boolean flag); +extern void IRO_LogForFunction(char *name); +extern void IRO_DumpFlowgraph(void); +extern void IRO_DumpNode(IRONode *node); +extern void IRO_DumpAssignments(void); +extern void IRO_DumpVars(void); +extern void IRO_DumpDf(void); +extern void IRO_DumpExprs(void); +extern void IRO_SetupDump(void); +extern void IRO_CleanupDump(void); +extern void IRO_Dump(char *format, ...); +extern void IRO_DumpAddr(IROAddrRecord *rec); +extern void IRO_SpellType(Type *type, char *buf); #endif diff --git a/includes/compiler/IroEmptyLoop.h b/includes/compiler/IroEmptyLoop.h index 6eb4edc..5268f18 100644 --- a/includes/compiler/IroEmptyLoop.h +++ b/includes/compiler/IroEmptyLoop.h @@ -1,6 +1,8 @@ #ifndef COMPILER_IROEMPTYLOOP_H #define COMPILER_IROEMPTYLOOP_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +extern void IRO_FindEmptyLoops(void); #endif diff --git a/includes/compiler/IroEval.h b/includes/compiler/IroEval.h index 2d650b7..9a4b2bf 100644 --- a/includes/compiler/IroEval.h +++ b/includes/compiler/IroEval.h @@ -1,6 +1,10 @@ #ifndef COMPILER_IROEVAL_H #define COMPILER_IROEVAL_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +// TODO +extern void IRO_TruncateBitfieldValueToType(CInt64 *val, Type *type, Type *type2); +extern void IRO_TruncateValueToType(CInt64 *val, Type *type); #endif diff --git a/includes/compiler/IroExprRegeneration.h b/includes/compiler/IroExprRegeneration.h index 2012c2d..aa43501 100644 --- a/includes/compiler/IroExprRegeneration.h +++ b/includes/compiler/IroExprRegeneration.h @@ -1,6 +1,8 @@ #ifndef COMPILER_IROEXPRREGENERATION_H #define COMPILER_IROEXPRREGENERATION_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +extern void IRO_RegenerateExpressions(void); #endif diff --git a/includes/compiler/IroFlowgraph.h b/includes/compiler/IroFlowgraph.h index 1faf2d9..3a76df0 100644 --- a/includes/compiler/IroFlowgraph.h +++ b/includes/compiler/IroFlowgraph.h @@ -1,6 +1,98 @@ #ifndef COMPILER_IROFLOWGRAPH_H #define COMPILER_IROFLOWGRAPH_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/BitVector.h" +#include "compiler/CError.h" +#include "compiler/CompilerTools.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +struct IRONode { + UInt16 index; + UInt16 numsucc; + UInt16 *succ; + UInt16 numpred; + UInt16 *pred; + IROLinear *first; + IROLinear *last; + BitVector *x16; // In + BitVector *x1A; // Out + BitVector *x1E; // Gen + BitVector *x22; // Kill + UInt32 x26; + BitVector *x2A; // AA + BitVector *dom; + IRONode *nextnode; + Boolean x36; + Boolean x37; + Boolean mustreach; + Boolean x39; + UInt16 loopdepth; + Boolean x3C; + struct ObjectSet *addressed; + Boolean mustreach1; +}; + +typedef struct IRONodes { + UInt16 *indices; + UInt16 num; + UInt16 base; +} IRONodes; + +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern UInt16 IRO_NumNodes; +extern IRONode *IRO_FirstNode; +extern IRONode *IRO_LastNode; +extern IRONode *IRO_EndNode; +extern IRONode **IRO_NodeTable; +extern BitVector *IRO_VarKills; +extern BitVector *IRO_Avail; +extern BitVector *IRO_FuncKills; +extern BitVector *IRO_ExprKills; + +extern void IRO_ComputeSuccPred(void); +extern void IRO_ComputeDom(void); +extern void IRO_BuildFlowgraph(IROLinear *linear); +extern IRONode *IRO_NewFlowGraphNode(void); +extern IRONode *IRO_MergeFlowGraphNodes(IRONode *a, IRONode *b); + +inline void IROFlowgraph_sub_4C2140(IRONodes *nodes) { + nodes->indices = oalloc(sizeof(UInt16) * IRO_NumNodes); + nodes->num = 0; + nodes->base = 0; +} + +inline void IROFlowgraph_sub_4C20E0(IRONodes *nodes) { +} + +inline UInt16 IROFlowgraph_sub_4C2040(IRONodes *nodes) { + return nodes->num; +} + +inline UInt16 IROFlowgraph_sub_4C2100(IRONodes *nodes) { + UInt16 result = -1; + if (nodes->num) { + result = nodes->indices[nodes->base]; + nodes->base = (nodes->base + 1) % IRO_NumNodes; + nodes->num--; + } + return result; +} + +inline void IROFlowgraph_sub_4C3880(IRONodes *nodes, UInt16 index) { + if (nodes->num < IRO_NumNodes) { + nodes->indices[(nodes->base + nodes->num) % IRO_NumNodes] = index; + nodes->num++; + } else { +#line 93 + CError_FATAL(); + } +} #endif diff --git a/includes/compiler/IroJump.h b/includes/compiler/IroJump.h index a2368c9..bbb5594 100644 --- a/includes/compiler/IroJump.h +++ b/includes/compiler/IroJump.h @@ -1,6 +1,12 @@ #ifndef COMPILER_IROJUMP_H #define COMPILER_IROJUMP_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +extern Boolean IRO_DoJumpChaining(void); +extern void IRO_MakeReachable(IRONode *node); +extern Boolean IRO_RemoveUnreachable(void); +extern Boolean IRO_RemoveRedundantJumps(void); +extern Boolean IRO_RemoveLabels(void); #endif diff --git a/includes/compiler/IroLinearForm.h b/includes/compiler/IroLinearForm.h index 9f2ece1..6ba0021 100644 --- a/includes/compiler/IroLinearForm.h +++ b/includes/compiler/IroLinearForm.h @@ -1,6 +1,163 @@ #ifndef COMPILER_IROLINEARFORM_H #define COMPILER_IROLINEARFORM_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/Switch.h" +#include "compiler/enode.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif + +typedef struct IROLinearIRSave { + IROLinear *firstLinear; + IROLinear *lastLinear; + UInt32 numLinear; + Statement *curStat; + Boolean disableDueToAsm; + Boolean isLeafFunction; + Boolean functionHasReturn; + void *nullCheckList; + Statement *currStmt; + Statement *prevStmt; +} IROLinearIRSave; + +typedef enum IROLinearType { + IROLinearNop, + IROLinearOperand, + IROLinearOp1Arg, + IROLinearOp2Arg, + IROLinearGoto, + IROLinearIf, + IROLinearIfNot, + IROLinearReturn, + IROLinearLabel, + IROLinearSwitch, + IROLinearOp3Arg, + IROLinearFunccall, + IROLinearEntry, + IROLinearExit, + IROLinearBeginCatch, + IROLinearEndCatch, + IROLinearEndCatchDtor, + IROLinearAsm, + IROLinear18, + IROLinear19, + IROLinearEnd +} IROLinearType; + +enum { + IROLF_1 = 0x1, + IROLF_Reffed = 0x2, + IROLF_Assigned = 0x4, + IROLF_8 = 0x8, + IROLF_Used = 0x10, + IROLF_Ind = 0x20, + IROLF_Subs = 0x40, + IROLF_80 = 0x80, + IROLF_LoopInvariant = 0x100, + IROLF_BeginLoop = 0x200, + IROLF_EndLoop = 0x400, + IROLF_Ris = 0x800, + IROLF_Immind = 0x1000, + IROLF_VecOp = 0x2000, + IROLF_4000 = 0x4000, + IROLF_8000 = 0x8000, + IROLF_VecOpBase = 0x10000, + IROLF_20000 = 0x20000, + IROLF_CounterLoop = 0x40000, + IROLF_BitfieldIndirect = 0x80000, + IROLF_CouldError = 0x100000 +}; + +// actual name is LinearNode as per mwccppc v8 +struct IROLinear { + IROLinearType type; + ENodeType nodetype; + SInt32 flags; + UInt16 nodeflags; + unsigned short index; + Statement *stmt; + Type *rtype; + IROExpr *expr; + struct ERange *x16; + PointsToFunction *pointsToFunction; + Boolean x1E; + union { + struct { + void *data1; + void *data2; + void *data3; + void *data4; + void *data5; + } idk; + // Operand + ENode *node; + // Op1Arg + IROLinear *monadic; + // Op2Arg + struct { + IROLinear *left; + IROLinear *right; + } diadic; + // Op3Arg + struct { + IROLinear *a; + IROLinear *b; + IROLinear *c; + } args3; + // Funccall + struct { + char ispascal; + short argCount; + IROLinear **args; + IROLinear *linear8; // funcref + TypeFunc *functype; + struct LocationSetSet *returnedLocs; + } funccall; + // Asm + Statement *asm_stmt; + // If, IfNot, Goto, Label + struct { + CLabel *label; + IROLinear *x4; // if,ifnot only?? + } label; + struct { + SwitchInfo *info; + IROLinear *x4; + } swtch; + // BeginCatch, EndCatch, EndCatchDtor + struct { + IROLinear *linear; + int x4; + int x8; + } ctch; + } u; + IROLinear *next; +}; + +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern IROLinear *IRO_FirstLinear; +extern IROLinear *IRO_LastLinear; +extern UInt32 IRO_NumLinear; +extern Statement *CurStat; + +extern IROLinear *IRO_NewLinear(IROLinearType type); +extern void IRO_PreLinearize(Statement *stmt); +extern void IRO_Linearize(Statement *stmt); +extern ENode *IRO_NewENode(ENodeType nodetype); +extern Statement *IRO_Delinearize(IRONode *node, IROLinear *linear); +extern void IRO_RenumberInts(void); +extern void IRO_UpdateFlagsOnInts(void); +extern void IRO_SaveLinearIR(IROLinearIRSave *save); +extern void IRO_RestoreLinearIR(IROLinearIRSave *save); + +#define IS_LINEAR_ENODE(_linear, _nodetype) ( ((_linear)->type == IROLinearOperand) && ((_linear)->u.node->type) == (_nodetype) ) +#define IS_LINEAR_MONADIC(_linear, _nodetype) ( ((_linear)->type == IROLinearOp1Arg) && ((_linear)->nodetype) == (_nodetype) ) +#define IS_LINEAR_DIADIC(_linear, _nodetype) ( ((_linear)->type == IROLinearOp2Arg) && ((_linear)->nodetype) == (_nodetype) ) +#define IS_LINEAR_DIADIC_2(_linear, _nodetype1, _nodetype2) ( ((_linear)->type == IROLinearOp2Arg) && (((_linear)->nodetype) == (_nodetype1) || ((_linear)->nodetype) == (_nodetype2)) ) #endif diff --git a/includes/compiler/IroLoop.h b/includes/compiler/IroLoop.h index 10bc36a..8357830 100644 --- a/includes/compiler/IroLoop.h +++ b/includes/compiler/IroLoop.h @@ -1,6 +1,111 @@ #ifndef COMPILER_IROLOOP_H #define COMPILER_IROLOOP_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/BitVector.h" + +typedef enum IROLoopIndFlags { + LoopInd_1 = 1, + LoopInd_2 = 2, + LoopInd_4 = 4, + LoopInd_8 = 8 +} IROLoopIndFlags; + +typedef enum IROLoopFlags { + LoopFlags_1 = 1, + LP_LOOP_HAS_CALLS = 2, + LP_LOOP_HAS_CNTRLFLOW = 4, + LoopFlags_8 = 8, + LP_INDUCTION_NOT_FOUND = 0x10, + LP_IFEXPR_NON_CANONICAL = 0x20, + LP_HAS_MULTIPLE_INDUCTIONS = 0x40, + LP_LOOP_HDR_HAS_SIDEEFFECTS = 0x80, + LoopFlags_100 = 0x100, + LoopFlags_200 = 0x200, + LP_LOOP_STEP_ISPOS = 0x400, + LoopFlags_800 = 0x800, + LoopFlags_1000 = 0x1000, + LoopFlags_2000 = 0x2000, + LP_LOOP_STEP_ISNEG = 0x4000, + LP_LOOP_HAS_ASM = 0x8000, + LoopFlags_10000 = 0x10000, + LoopFlags_20000 = 0x20000, + LoopFlags_40000 = 0x40000 +} IROLoopFlags; + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct IROLoopInd { + IROLoopIndFlags flags; + VarRecord *var; + IRONode *fnode; + IROLinear *nd; + SInt32 addConst; + IROLinear *addNode; + struct IROLoopInd *next; +} IROLoopInd; + +struct IROLoop { + SInt32 flags; + IRONode *fnode; + int x8; + int xC; + int x10; + IROLinear *nd14; // assignment expression that sets the initial value of induction + IROLinear *nd18; + IROLoopInd *induction; + int index20; + int index24; + CInt64 x28; + CInt64 x30; + int sizeBySomeMeasurement; +}; + +typedef enum IROLoopMemRefFlags { + LoopMemRef_1 = 1, + LoopMemRef_2 = 2, + LoopMemRef_4 = 4, + LoopMemRef_8 = 8, + LoopMemRef_10 = 0x10 +} IROLoopMemRefFlags; + +typedef struct IROLoopMemRef { + IROLoopMemRefFlags flags; + IROLinear *nd; + IROElmList *list; + IROAddrRecord *rec; + struct IROLoopMemRef *next; +} IROLoopMemRef; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern IRONode *LoopNode; +extern Boolean ConditionalHeaderAtBottom; +extern IROLoopInd *FirstInd; +extern BitVector *InLoop; +extern IROList IRO_InitLList; +extern BitVector *InLoop_Exits; +extern BitVector *InLoop_Tails; +extern UInt32 LoopExitNumber; +extern UInt32 LoopTailNum; +extern IRONode *LoopExitSuccessor; +extern IRONode *LoopTail; +extern IROLoopMemRef *IRO_LoopMemRefFirst; +extern IROLoopMemRef *IRO_LoopMemRefCurrent; + +extern void FindMustReach(void); +extern void FindMustReach1(IRONode *checkfnode); +extern void AddPreds(IRONode *fnode); +extern void IncLoopDepth(void); +extern void IRO_SetLoopDepth(void); +extern void IRO_FindLoops(void); +extern void ComputeLoopKills(void); +extern void ComputeLoopInvariance(void); +extern void ComputeLoopInduction(void); +extern void FindAssignmenttoInductionVar(IROLoop *loop, IRONode *fnode); +extern IROLoop *ExtractLoopInfo(IRONode *fnode); +extern CLabel *BuildLabel(IROList *list); #endif diff --git a/includes/compiler/IroMalloc.h b/includes/compiler/IroMalloc.h index bc7df31..f203a3d 100644 --- a/includes/compiler/IroMalloc.h +++ b/includes/compiler/IroMalloc.h @@ -1,6 +1,15 @@ #ifndef COMPILER_IROMALLOC_H #define COMPILER_IROMALLOC_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +extern size_t IRO_msize(void *buf); +extern void *IRO_malloc(size_t size); +extern void IRO_free(void *buf); +extern void *IRO_realloc(void *buf, size_t newsize); +extern void *IRO_calloc(size_t a, size_t b); +extern void IRO_pool_free_all(void); +extern void IRO_InitializeAllocator(void); +extern void IRO_TerminateAllocator(void); #endif diff --git a/includes/compiler/IroPointerAnalysis.h b/includes/compiler/IroPointerAnalysis.h index f6912cb..3266047 100644 --- a/includes/compiler/IroPointerAnalysis.h +++ b/includes/compiler/IroPointerAnalysis.h @@ -1,6 +1,25 @@ #ifndef COMPILER_IROPOINTERANALYSIS_H #define COMPILER_IROPOINTERANALYSIS_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +extern void PointerAnalysis_Setup(void); +extern void PointerAnalysis_Cleanup(void); +extern void IRO_AnalyzePointers(Object *function); +extern Boolean PointerAnalysis_TwoLinearNodePointerExprsMightAlias(Object *proc, IROLinear *nd1, IROLinear *nd2); +extern Boolean PointerAnalysis_TwoENodePointerExprsMightAlias(Object *proc, ENode *nd1, ENode *nd2); +extern Boolean PointerAnalysis_IsLinearNodePointerExprDefinite(Object *proc, IROLinear *nd); +extern Boolean PointerAnalysis_IsENodePointerExprDefinite(Object *proc, ENode *nd); +extern Boolean PointerAnalysis_IsVariableValueDefinite(Object *proc, VarRecord *var, PointsToFunction *pointsTo); +extern void PointerAnalysis_LookupLinearNodePointerExpr(Object *proc, IROLinear *indirect, IROListNode **list); +extern void PointerAnalysis_LookupENodePointerExpr(Object *proc, ENode *indirect, ENodeList **list); +extern void PointerAnalysis_LookupVariableIntoLinearNodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, IROList **list); +extern void PointerAnalysis_LookupVariableIntoENodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, ENodeList **list); +extern void PointerAnalysis_GetFunctionKills(Object *proc, IROLinear *funccall, ObjectList **list); +extern void PointerAnalysis_GetFunctionDependencies(Object *proc, IROLinear *funccall, ObjectList **list); +extern void PointerAnalysis_PragmaMode(void); +extern void PointerAnalysis_ParseEntryPointsToSpecifier(DeclInfo *di); +extern void PointerAnalysis_ParseExitPointsToSpecifier(DeclInfo *di); +extern void PointerAnalysis_ParseFunctionModifiesSpecifier(DeclInfo *di); #endif diff --git a/includes/compiler/IroPropagate.h b/includes/compiler/IroPropagate.h index 689b5fa..a61e526 100644 --- a/includes/compiler/IroPropagate.h +++ b/includes/compiler/IroPropagate.h @@ -1,6 +1,35 @@ #ifndef COMPILER_IROPROPAGATE_H #define COMPILER_IROPROPAGATE_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/BitVector.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +struct IROAssign { + IROLinear *linear; + UInt16 index; + UInt16 varIndex; + IROLinear *linear2; + BitVector *depends; + Object *varObj; + VarRecord *var; + IROAssign *next; + IROAssign *prev; + UInt16 x20; + IRONode *node; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern IROAssign *IRO_FirstAssign; +extern IROAssign *IRO_LastAssign; +extern SInt32 IRO_NumAssign; + +extern int IRO_IsRegable(Object *obj); +extern Boolean IRO_CopyAndConstantPropagation(void); +extern void IRO_ExpressionPropagation(void); #endif diff --git a/includes/compiler/IroRangePropagation.h b/includes/compiler/IroRangePropagation.h index 210cd9e..fea6542 100644 --- a/includes/compiler/IroRangePropagation.h +++ b/includes/compiler/IroRangePropagation.h @@ -1,6 +1,8 @@ #ifndef COMPILER_IRORANGEPROPAGATION_H #define COMPILER_IRORANGEPROPAGATION_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +extern Boolean IRO_RangePropagateInFNode(void); #endif diff --git a/includes/compiler/IroSubable.h b/includes/compiler/IroSubable.h index ff0cbd9..7a3c344 100644 --- a/includes/compiler/IroSubable.h +++ b/includes/compiler/IroSubable.h @@ -1,6 +1,10 @@ #ifndef COMPILER_IROSUBABLE_H #define COMPILER_IROSUBABLE_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +extern void IRO_InitializeIsSubableOpArray(void); +extern Boolean IRO_IsSubableExpression(IROLinear *nd); +extern Boolean IRO_IsVectorTempCandidate(IROLinear *nd); #endif diff --git a/includes/compiler/IroTransform.h b/includes/compiler/IroTransform.h new file mode 100644 index 0000000..0ec4f4c --- /dev/null +++ b/includes/compiler/IroTransform.h @@ -0,0 +1,9 @@ +#ifndef COMPILER_IROTRANSFORM_H +#define COMPILER_IROTRANSFORM_H + +#include "compiler/IrOptimizer.h" + +// TODO +extern Boolean IRO_TransformSelfAssignmentToAssignment(IROLinear *linear); + +#endif diff --git a/includes/compiler/IroUnrollLoop.h b/includes/compiler/IroUnrollLoop.h index b48510f..9e08d03 100644 --- a/includes/compiler/IroUnrollLoop.h +++ b/includes/compiler/IroUnrollLoop.h @@ -1,6 +1,22 @@ #ifndef COMPILER_IROUNROLLLOOP_H #define COMPILER_IROUNROLLLOOP_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" + +extern void IRO_LoopUnroller(void); +extern void IRO_IterateForLoopBody(); +extern void IRO_LinearizeForLoopPostLoop(); +extern void BuildEarlyLoopExitTest(); +extern void BuildLoopExitTest(); +extern void IsIterationCountConstant(); +extern void NoOpBlock(); +extern void IRO_TestConstantIterationCount(); +extern void BuildOrigIterationCount(); +extern void BuildNewFinalvalue(); +extern void BuildUnrolledBodyEntryTest(); +extern void ChangeInductionReference(); +extern void UpdateInductionIncrement(); +extern void GenInitialAssignment(); +extern void GenNewInduction(); #endif diff --git a/includes/compiler/IroUtil.h b/includes/compiler/IroUtil.h index b4c71e7..68d34f5 100644 --- a/includes/compiler/IroUtil.h +++ b/includes/compiler/IroUtil.h @@ -1,6 +1,112 @@ #ifndef COMPILER_IROUTIL_H #define COMPILER_IROUTIL_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/CParser.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +struct IROList { + IROLinear *head; + IROLinear *tail; +}; + +struct IROListNode { + IROList list; + IROListNode *nextList; +}; + +struct IROElmList { + void *element; + IROElmList *next; +}; + +struct IROAddrRecord { + IROLinear *linear; + unsigned short numObjRefs; + IROElmList *objRefs; + unsigned short numMisc; + IROElmList *misc; + unsigned short numInts; + IROElmList *ints; + int x16; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern Object *FunctionName; +extern Boolean IRO_IsLeafFunction; +extern Boolean IRO_FunctionHasReturn; +extern Boolean DisableDueToAsm; +extern Boolean LoopOptimizerRun; + +extern Object *IRO_IsVariable(IROLinear *linear); +extern Boolean IRO_IsConstant(IROLinear *linear); +extern Boolean IRO_IsPow2(IROLinear *linear, SInt32 *powvalue); +extern Boolean IRO_IsIntConstant(IROLinear *linear); +extern Boolean IRO_IsFloatConstant(IROLinear *linear); +extern Boolean IRO_IsVector128Constant(IROLinear *linear); +extern Boolean IRO_IsAssignment(IROLinear *linear); +extern Boolean IRO_TypesEqual(Type *a, Type *b); +extern Type *IRO_UnsignedType(Type *type); +extern Type *IRO_SignedType(Type *type); +extern Boolean IRO_is_CPtypeequal(Type *a, Type *b); +extern Boolean IRO_ExprsSame(IROLinear *a, IROLinear *b); +extern CLabel *IRO_NewLabel(void); +extern Boolean IRO_ExprsSameSemantically(IROLinear *a, IROLinear *b); +extern IROLinear *IRO_FindPrecedAfter(IROLinear *a, IROLinear *iter); +extern IROLinear *IRO_FindPreced(IROLinear *a); +extern IROLinear *IRO_FindFirst(IROLinear *linear); +extern void IRO_CutAndPasteAfter(IROLinear *a, IROLinear *b, IROLinear *c); +extern Boolean IRO_IsConstantZero(IROLinear *linear); +extern Boolean IRO_IsConstantOne(IROLinear *linear); +extern Boolean IRO_IsConstantNegativeOne(IROLinear *linear); +extern void IRO_NopOut(IROLinear *linear); +extern void IRO_NopNonSideEffects(IROLinear *linear, SInt32 level); +extern void IRO_BuildList(IROLinear *linear, Boolean isEntry); +typedef void (*IROWalkTreeFunc)(IROLinear *linear, Boolean isEntry); +extern void IRO_WalkTree(IROLinear *linear, IROWalkTreeFunc func); +extern void IRO_WalkTreeToPropagateFlags(IROLinear *linear, IROWalkTreeFunc func); +extern void IRO_WalkInts(IROLinear *a, IROLinear *b, IROWalkTreeFunc func); +extern void IRO_Cut(IROLinear *a, IROLinear *b); +extern void IRO_Paste(IROLinear *a, IROLinear *b, IROLinear *c); +extern void IRO_PasteAfter(IROLinear *a, IROLinear *b, IROLinear *c); +extern void IRO_ClipExpr(IROExpr *expr); +extern void IRO_ClipExprTree(IROLinear *linear); +extern void IRO_MoveExpression(IROExpr *expr, IROLinear *linear); +extern void IRO_InitList(IROList *list); +extern void IRO_AddToList(IROLinear *linear, IROList *list); +extern IROLinear *IRO_FindLabelNode(CLabel *label, IROLinear *linear); +extern void IRO_DuplicateExprRange(IROLinear *start, IROLinear *end, IROList *list); +extern IROLinear *IRO_DuplicateExpr(IROLinear *linear, IROList *list); +extern IROLinear *IRO_TempReference(Object *obj, IROList *list); +extern IROLinear *IRO_LocateFather(IROLinear *linear); +extern IROLinear *IRO_LocateFather_Cut_And_Paste(IROLinear *a, IROLinear *b); +extern IROLinear *IRO_LocateFather_Cut_And_Paste_Without_Nopping(IROLinear *a, IROLinear *b); +extern void IRO_ReplaceReference(IROLinear *a, Object *obj, IROLinear *b); +extern void IRO_ReplaceReferenceWithNode(IROLinear *a, IROLinear *b); +extern void IRO_GetTemp(IROExpr *expr); +extern IROLinear *IRO_AssignToTemp(IROExpr *expr); +extern IROLinear *IRO_FindStart(IROLinear *linear); +extern void IRO_DeleteCommaNode(IROLinear *linear, IROExpr *expr); +extern void IRO_RemoveCommaNodeFromIR(void); +extern IROAddrRecord *IRO_InitAddrRecordPointer(IROLinear *linear); +extern IROLinear *IRO_HasSideEffect(IROLinear *linear); +extern IROLinear *IRO_CheckSideEffect(IROLinear *linear); +typedef void (*WalkObjFunc)(Object *obj); +extern void IRO_WalkExcActions(ExceptionAction *action, WalkObjFunc func); +extern Boolean IRO_FunctionCallMightThrowException(IROLinear *linear); +extern IROLinear *IRO_NewIntConst(CInt64 val, Type *type); +extern IROLinear *IRO_NewFloatConst(Float val, Type *type); +extern Boolean IRO_IsAddressMultiply(IROLinear *linear); +extern void IRO_SetupForUserBreakChecking(void); +extern void IRO_CheckForUserBreak(void); + +// TODO is this elsewhere? +inline Boolean IRO_IsUnsignedType(Type *type) { + return is_unsigned(type); +} #endif diff --git a/includes/compiler/IroVars.h b/includes/compiler/IroVars.h index 3fbfc2f..9df9ae5 100644 --- a/includes/compiler/IroVars.h +++ b/includes/compiler/IroVars.h @@ -1,6 +1,51 @@ #ifndef COMPILER_IROVARS_H #define COMPILER_IROVARS_H -#include "compiler/common.h" +#include "compiler/IrOptimizer.h" +#include "compiler/enode.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +struct VarRecord { + UInt16 index; + Object *object; + int x6; + Boolean xA; + Boolean xB; + Boolean xC; + VarRecord *next; + IRODef *defs; + IROUse *uses; + Type *x1A; // bitfield-related + IROLinear *x1E; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern VarRecord *IRO_FirstVar; +extern VarRecord *IRO_LastVar; +extern SInt32 IRO_NumVars; +extern Boolean IRO_IsBitField; +extern SInt32 IRO_BaseTerms; +extern SInt32 IRO_VarTerms; +extern Boolean IRO_IsModifyOp[MAXEXPR]; +extern Boolean IRO_IsAssignOp[MAXEXPR]; + +extern void IRO_InitializeIRO_IsModifyOpArray(void); +extern void IRO_InitializeIRO_IsAssignOpArray(void); +extern VarRecord *IRO_FindVar(Object *object, Boolean flag1, Boolean flag2); +extern void IRO_FindAllVars(void); +extern void IRO_ZapVarPtrs(void); +extern void IRO_UpdateVars(void); +extern void IRO_AddElmToList(IROLinear *linear, IROElmList **list); +extern void IRO_DecomposeAddressExpression(IROLinear *linear, IROAddrRecord *rec); +extern void IRO_DecomposeAddressExpression_Cheap(IROLinear *linear); +extern VarRecord *IRO_FindAssigned(IROLinear *linear); +extern void IRO_GetKills(IROLinear *linear); +extern void IRO_CheckInit(void); +extern void IRO_RewriteBitFieldTemps(void); +extern void IRO_ScalarizeClassDataMembers(void); #endif diff --git a/includes/compiler/LiveInfo.h b/includes/compiler/LiveInfo.h new file mode 100644 index 0000000..6f70c59 --- /dev/null +++ b/includes/compiler/LiveInfo.h @@ -0,0 +1,18 @@ +#ifndef COMPILER_LIVEINFO_H +#define COMPILER_LIVEINFO_H + +#include "compiler/common.h" + +typedef struct LiveInfo { + UInt32 *vec0; // use + UInt32 *vec4; // def + UInt32 *vec8; // in + UInt32 *vecC; // out +} LiveInfo; + +extern LiveInfo *liveinfo; + +extern void computelivevariables(Object *proc); +extern int dead(PCode *instr, char rclass, UInt32 *vec); + +#endif diff --git a/includes/compiler/LoadDeletion.h b/includes/compiler/LoadDeletion.h index 743d5bb..b19fd2e 100644 --- a/includes/compiler/LoadDeletion.h +++ b/includes/compiler/LoadDeletion.h @@ -3,4 +3,8 @@ #include "compiler/common.h" +extern int deletedloads; + +extern void deletedeadloads(Object *proc); + #endif diff --git a/includes/compiler/LoopDetection.h b/includes/compiler/LoopDetection.h index 7f27467..28dbb7a 100644 --- a/includes/compiler/LoopDetection.h +++ b/includes/compiler/LoopDetection.h @@ -2,5 +2,97 @@ #define COMPILER_LOOPDETECTION_H #include "compiler/common.h" +#include "compiler/BitVector.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct BlockList { + struct BlockList *next; + PCodeBlock *block; +} BlockList; + +typedef struct InstrList { + struct InstrList *next; + PCode *instr; +} InstrList; + +typedef enum LoopBound { + LOOP_BOUND_INDETERMINATE, + LOOP_BOUND_CONSTANT, + LOOP_BOUND_VARIABLE +} LoopBound; + +typedef struct Loop { + struct Loop *parent; + struct Loop *nextSibling; + struct Loop *children; + PCodeBlock *body; // repeated block + PCodeBlock *preheader; // block at the start of the loop + PCodeBlock *footer; // block at the end of the loop + PCode *pc18; + BlockList *blocks; + UInt32 *memberblocks; + UInt32 *vec24; + UInt32 *vec28; + UInt32 *vec2C; + struct BasicInductionVar *basicInductionVars; + int loopWeight; + int bodySize; // amount of instructions in the body + SInt32 iterationCount; + SInt32 lower; + SInt32 upper; + SInt32 step; // value added in each iteration + unsigned char unknownCondition; + Boolean x4D; + Boolean x4E; + Boolean x4F; + Boolean isUnknownCountingLoop; // is a counting loop with non-constant iteration count + Boolean isKnownCountingLoop; + Boolean x52; + Boolean x53; + Boolean x54; + LoopBound lowerType; + LoopBound upperType; + Boolean x57; +} Loop; + +typedef struct BasicInductionVar { + struct BasicInductionVar *next; + Loop *loop; + struct InductionVar *inductionVars; + InstrList *instrsC; + PCode *initializer; + SInt32 step; + short reg; +} BasicInductionVar; + +typedef struct InductionVar { + struct InductionVar *next; + BasicInductionVar *basicVar; + PCode *instr; + PCode *instrC; + Loop *someloop; + SInt32 step; + short x18; // arg index within instr + short x1A; // arg index within instr + short x1C; // reg + short x1E; // reg +} InductionVar; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern Loop *loopsinflowgraph; +extern int loopdetection_nblocks; +extern BitVector *LoopTemp; +extern void *LoopList_First; + +extern void addblocktoloop(Loop *loop, PCodeBlock *block); +extern void insertpreheaderblock(Loop *loop); +extern void findloopsinflowgraph(void); +extern void analyzeForCountableLoops(Loop *loop); +extern void analyzeloop(Loop *loop); +extern void analyzeloopsinflowgraph(void); #endif diff --git a/includes/compiler/LoopOptimization.h b/includes/compiler/LoopOptimization.h index 5911b03..cffc7be 100644 --- a/includes/compiler/LoopOptimization.h +++ b/includes/compiler/LoopOptimization.h @@ -3,4 +3,12 @@ #include "compiler/common.h" +extern int optimizedloops; +extern int optimizedloop_full_unroll; +extern int optimizedloop_trans_regs; + +extern void pccomputepredecessors1(PCodeBlock *block); +extern void changearraytoregisters(void); +extern void optimizeloops(void); + #endif diff --git a/includes/compiler/ObjGenMachO.h b/includes/compiler/ObjGenMachO.h index ba06522..8d97616 100644 --- a/includes/compiler/ObjGenMachO.h +++ b/includes/compiler/ObjGenMachO.h @@ -3,4 +3,7 @@ #include "compiler/common.h" +// more stuff goes here +extern void ObjGen_DeclareSwitchTable(Object *a, Object *b); + #endif diff --git a/includes/compiler/PCode.h b/includes/compiler/PCode.h index b56ed2f..cebab6f 100644 --- a/includes/compiler/PCode.h +++ b/includes/compiler/PCode.h @@ -16,7 +16,10 @@ enum { EffectRead = 1, - EffectWrite = 2 + EffectWrite = 2, + Effect4 = 4, + Effect8 = 8, + Effect40 = 0x40 // spilled register? }; /*typedef enum { @@ -48,7 +51,7 @@ typedef enum { struct PCodeArg { PCOpKind kind; - char arg; + unsigned char arg; union { struct { unsigned short effect; @@ -74,14 +77,46 @@ struct PCodeArg { } data; }; +#define PC_OP_IS_REGISTER(_op, _rclass, _reg) \ +((_op)->kind == PCOp_REGISTER && \ + (char) (_op)->arg == (_rclass) && \ + (_op)->data.reg.reg == (_reg)) + +#define PC_OP_IS_READ_REGISTER(_op, _rclass, _reg) \ +((_op)->kind == PCOp_REGISTER && \ + (char) (_op)->arg == (_rclass) && \ + (_op)->data.reg.reg == (_reg) && \ + ((_op)->data.reg.effect & EffectRead)) + +#define PC_OP_IS_WRITE_REGISTER(_op, _rclass, _reg) \ +((_op)->kind == PCOp_REGISTER && \ + (char) (_op)->arg == (_rclass) && \ + (_op)->data.reg.reg == (_reg) && \ + ((_op)->data.reg.effect & EffectWrite)) + +#define PC_OP_IS_ANY_REGISTER(_op, _rclass) \ +((_op)->kind == PCOp_REGISTER && \ + (char) (_op)->arg == (_rclass)) + +#define PC_OP_IS_READ_ANY_REGISTER(_op, _rclass) \ +((_op)->kind == PCOp_REGISTER && \ + (char) (_op)->arg == (_rclass) && \ + ((_op)->data.reg.effect & EffectRead)) + +#define PC_OP_IS_WRITE_ANY_REGISTER(_op, _rclass) \ +((_op)->kind == PCOp_REGISTER && \ + (char) (_op)->arg == (_rclass) && \ + ((_op)->data.reg.effect & EffectWrite)) + + struct PCode { PCode *nextPCode; PCode *prevPCode; PCodeBlock *block; - unsigned int xx_C; - unsigned int _10; - int flags; - void *_18; + int useID; + int defID; + UInt32 flags; + struct Alias *alias; SInt32 sourceoffset; short op; short argCount; @@ -92,7 +127,7 @@ struct PCodeLabel { PCodeLabel *nextLabel; PCodeBlock *block; short resolved; - short index; + unsigned short index; }; typedef struct _PCLink { @@ -118,8 +153,8 @@ struct PCodeBlock { /* PCode Flags */ enum { fPCodeFlag1 = 1, - fPCodeFlag2 = 2, - fPCodeFlag4 = 4, + fPCodeFlag2 = 2, // some kinda load + fPCodeFlag4 = 4, // some kinda store fPCodeFlag8 = 8, fPCodeFlag10 = 0x10, fPCodeFlag20 = 0x20, @@ -134,8 +169,8 @@ enum { fCommutative = 0x2000, fIsCSE = 0x4000, fPCodeFlag8000 = 0x8000, - fPCodeFlag20000 = 0x20000, // ? - fPCodeFlag40000 = 0x40000, // ? + fPCodeFlag20000 = 0x20000, // some kinda load? + fPCodeFlag40000 = 0x40000, // some kinda store? // Set 1 only fLink = 0x1000000, fBranchNotTaken = 0x4000000, @@ -150,7 +185,7 @@ enum { fPCodeFlag4000000 = 0x4000000, fPCodeFlag8000000 = 0x8000000, fPCodeFlag10000000 = 0x10000000, - fPCodeFlag20000000 = 0x20000000, + fPCodeFlag20000000 = 0x20000000, // record bit? fPCodeFlag40000000 = 0x40000000, fPCodeFlag80000000 = 0x80000000 }; @@ -159,9 +194,10 @@ enum { fPCBlockFlag1 = 1, // prologue fPCBlockFlag2 = 2, // epilogue fPCBlockFlag4 = 4, - fPCBlockFlag8 = 8, + fPCBlockFlag8 = 8, // scheduled? fPCBlockFlag10 = 0x10, fPCBlockFlag20 = 0x20, + fPCBlockFlag2000 = 0x2000, fPCBlockFlag4000 = 0x4000 }; diff --git a/includes/compiler/PCodeAssembly.h b/includes/compiler/PCodeAssembly.h index 682482c..41082a3 100644 --- a/includes/compiler/PCodeAssembly.h +++ b/includes/compiler/PCodeAssembly.h @@ -3,4 +3,8 @@ #include "compiler/common.h" +extern UInt32 assemblepcode(PCode *instr, UInt32 offset, PCodeArg *dummyArg); +extern void optimizefinalbranches(); +extern void assemblefunction(); + #endif diff --git a/includes/compiler/PCodeInfo.h b/includes/compiler/PCodeInfo.h index c7cee47..8f81179 100644 --- a/includes/compiler/PCodeInfo.h +++ b/includes/compiler/PCodeInfo.h @@ -17,6 +17,10 @@ typedef enum { PCOp_PLACEHOLDEROPERAND } PCOpKind; +typedef enum { + PCOpMemory1 = 1 +} PCOpMemoryArg; + typedef struct _OpcodeInfo { const char *name; const char *format; diff --git a/includes/compiler/PCodeListing.h b/includes/compiler/PCodeListing.h index 32390ac..994fd83 100644 --- a/includes/compiler/PCodeListing.h +++ b/includes/compiler/PCodeListing.h @@ -3,4 +3,36 @@ #include "compiler/common.h" +extern int pclist_bad_operand; + +extern void pcinitlisting(void); +extern void pccleanuplisting(void); +extern void pclistblocks(char *name1, char *name2); +extern void pclistdataflow(void); +extern void pclistinterferences(char *class_format, int regcount); +extern void pclistspill(void); +extern void pclistcopypropitem(void); +extern void pclistcoalesce(void); +extern void pclistusedefs(void); +extern void pclistpropinfo(void); +extern void pclistloops(void); +extern void pclistswitchtables(void); +extern void pclistdominators(void); +extern void pclistbackedge(void); +extern void pclistinterferencegraphnode(void); +extern void pclistinterferencegraph(void); +extern void pclistblock_scheduler(void); +extern void pclistblocks_start_scheduler(char *str1, char *str2); +extern void pclistblocks_end_scheduler(void); +extern void pctotalheap(void); +extern void pctotalmemory(void); +extern void pcmessage(char *probably_a_string, ...); +extern int formatalias(Alias *alias, char *buf, int bufSize); +extern int dumpalias(Alias *alias, int len, Boolean flag1, Boolean flag2); +extern void pcformatset(void); +extern int GetLineEndOffset(char *str, int lineNum, int len); +extern int GetLineOffset(char *str, int lineNum, int len); +extern void DumpSourceCode(void); +extern int DumpIR_SrcBreak(void); + #endif diff --git a/includes/compiler/Registers.h b/includes/compiler/Registers.h index 692d9dc..4d02306 100644 --- a/includes/compiler/Registers.h +++ b/includes/compiler/Registers.h @@ -4,16 +4,29 @@ #include "compiler/common.h" enum { + Register0 = 0, + Register2 = 2, RegisterMax = 32 }; -const char RegClass_SPR = 0; +/*const char RegClass_SPR = 0; const char RegClass_CRFIELD = 1; const char RegClass_VR = 2; const char RegClass_FPR = 3; const char RegClass_GPR = 4; const char RegClassMax = 5; const char RegClass_6 = 6; -const char RegClass_DCR = 7; +const char RegClass_DCR = 7;*/ +typedef enum RegClass { + RegClass_Invalid = -1, + RegClass_SPR = 0, + RegClass_CRFIELD = 1, + RegClass_VR = 2, + RegClass_FPR = 3, + RegClass_GPR = 4, + RegClassMax = 5, + RegClass_6 = 6, + RegClass_DCR = 7 +} RegClass; enum { RegState0 = 0, diff --git a/includes/compiler/Scheduler.h b/includes/compiler/Scheduler.h index 535bab5..1518e3a 100644 --- a/includes/compiler/Scheduler.h +++ b/includes/compiler/Scheduler.h @@ -3,4 +3,46 @@ #include "compiler/common.h" +typedef int (*LatencyFunc)(PCode *instr); +typedef void (*InitializeFunc)(void); +typedef int (*CanIssueFunc)(PCode *instr); +typedef void (*IssueFunc)(PCode *instr); +typedef void (*AdvanceClockFunc)(void); +typedef int (*SerializesFunc)(PCode *instr); +typedef int (*UsesVPermuteUnitFunc)(PCode *instr); + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct MachineInfo { + int x0; + int x4; + int x8; + LatencyFunc latency; + InitializeFunc initialize; + CanIssueFunc can_issue; + IssueFunc issue; + AdvanceClockFunc advance_clock; + SerializesFunc serializes; + UsesVPermuteUnitFunc uses_vpermute_unit; +} MachineInfo; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern MachineInfo machine601; +extern MachineInfo machine603; +extern MachineInfo machine603e; +extern MachineInfo machine604; +extern MachineInfo machine7400; +extern MachineInfo machine7450; +extern MachineInfo machine750; +extern MachineInfo machine821; + +extern int is_same_operand(PCodeArg *a, PCodeArg *b); +extern void scheduleinstructions(Boolean flag); +extern int is_dependent(PCode *a, PCode *b, char rclass); +extern int uses_vpermute_unit(PCode *instr); +extern int default_uses_vpermute_unit(PCode *instr); + #endif diff --git a/includes/compiler/SpillCode.h b/includes/compiler/SpillCode.h index 3d6b911..1685e84 100644 --- a/includes/compiler/SpillCode.h +++ b/includes/compiler/SpillCode.h @@ -3,4 +3,7 @@ #include "compiler/common.h" +extern void estimatespillcosts(void); +extern void insertspillcode(void); + #endif diff --git a/includes/compiler/StrengthReduction.h b/includes/compiler/StrengthReduction.h index 3686c4b..6c22452 100644 --- a/includes/compiler/StrengthReduction.h +++ b/includes/compiler/StrengthReduction.h @@ -3,4 +3,8 @@ #include "compiler/common.h" +extern int strengthreducedloops; + +extern void strengthreduceloops(void); + #endif diff --git a/includes/compiler/UseDefChains.h b/includes/compiler/UseDefChains.h index bcdbfe0..6957897 100644 --- a/includes/compiler/UseDefChains.h +++ b/includes/compiler/UseDefChains.h @@ -2,5 +2,65 @@ #define COMPILER_USEDEFCHAINS_H #include "compiler/common.h" +#include "compiler/Registers.h" +#include "compiler/PCodeInfo.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct TinyValue { + PCOpKind kind; + unsigned char arg; + union { + short reg; + Object *object; + } u; +} TinyValue; + +typedef struct UseDefInfo { + UInt32 *defvec0; + UInt32 *defvec4; + UInt32 *defvec8; + UInt32 *defvecC; + UInt32 *usevec10; + UInt32 *usevec14; + UInt32 *usevec18; + UInt32 *usevec1C; +} UseDefInfo; + +typedef struct UseOrDef { + PCode *pcode; + TinyValue v; +} UseOrDef; + +typedef struct RegUseOrDef { + struct RegUseOrDef *next; + int id; +} RegUseOrDef; + +typedef struct ObjectUseDef { + struct ObjectUseDef *next; + struct ObjectUseDef *leftchild; + struct ObjectUseDef *rightchild; + Object *object; + RegUseOrDef *uses; + RegUseOrDef *defs; +} ObjectUseDef; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern int number_of_Defs; +extern UseOrDef *Defs; +extern RegUseOrDef **reg_Defs[RegClassMax]; +extern int number_of_Uses; +extern UseOrDef *Uses; +extern RegUseOrDef **reg_Uses[RegClassMax]; +extern UseDefInfo *usedefinfo; +extern ObjectUseDef *objectusedefs; +extern ObjectUseDef *objectusedeflist; + +extern ObjectUseDef *findobjectusedef(Object *object); +extern void computeusedefchains(int flag); #endif diff --git a/includes/compiler/ValueNumbering.h b/includes/compiler/ValueNumbering.h index 0d15e5a..a3c2fee 100644 --- a/includes/compiler/ValueNumbering.h +++ b/includes/compiler/ValueNumbering.h @@ -3,4 +3,17 @@ #include "compiler/common.h" +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +extern int removedcommonsubexpressions; +extern int nextvaluenumber; + +extern void killmemory(Alias *alias, PCode *newValue); +extern void removecommonsubexpressions(Object *proc, int flag); + #endif diff --git a/includes/compiler/VectorArraysToRegs.h b/includes/compiler/VectorArraysToRegs.h index ab0a966..80e39f3 100644 --- a/includes/compiler/VectorArraysToRegs.h +++ b/includes/compiler/VectorArraysToRegs.h @@ -3,4 +3,6 @@ #include "compiler/common.h" +extern int vectorarraystoregs(void); + #endif diff --git a/includes/compiler/common.h b/includes/compiler/common.h index 48a33dc..5a1bd48 100644 --- a/includes/compiler/common.h +++ b/includes/compiler/common.h @@ -112,6 +112,7 @@ typedef enum Section { N_SECTIONS = 45 } Section; +typedef struct Alias Alias; typedef struct BClassList BClassList; typedef struct CI_FuncData CI_FuncData; typedef struct CLabel CLabel; diff --git a/includes/compiler/enode.h b/includes/compiler/enode.h index 92c7d2c..833c90e 100644 --- a/includes/compiler/enode.h +++ b/includes/compiler/enode.h @@ -279,14 +279,67 @@ enum { }; #define ENODE_IS(_enode, _etype) ( (_enode)->type == (_etype) ) -#define ENODE_IS2(_enode, _etype1, _etype2) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS(_enode, (_etype2)) ) -#define ENODE_IS3(_enode, _etype1, _etype2, _etype3) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS(_enode, (_etype2)) || ENODE_IS(_enode, (_etype3)) ) +#define ENODE_IS2(_enode, _etype1, _etype2) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS((_enode), (_etype2)) ) +#define ENODE_IS3(_enode, _etype1, _etype2, _etype3) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS((_enode), (_etype2)) || ENODE_IS((_enode), (_etype3)) ) +#define ENODE_IS4(_enode, _etype1, _etype2, _etype3, _etype4) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS((_enode), (_etype2)) || ENODE_IS((_enode), (_etype3)) || ENODE_IS((_enode), (_etype4)) ) #define ENODE_IS_RANGE(_enode, _lo, _hi) ( ((_enode)->type >= (_lo)) && ((_enode)->type <= (_hi)) ) #define ENODE_QUALS(_enode) ( (UInt32) ( (_enode)->flags & ENODE_FLAG_QUALS ) ) #define ENODE_IS_INDIRECT_TO(_enode, _etype) ( ENODE_IS((_enode), EINDIRECT) && ENODE_IS((_enode)->data.monadic, (_etype)) ) #define ENODE_IS_ASSIGN(_enode) ( ENODE_IS_RANGE((_enode), EASS, EORASS) ) #define ENODE_IS_ASSIGN_TO(_enode, _etype) ( ENODE_IS_RANGE((_enode), EASS, EORASS) && ENODE_IS((_enode)->data.diadic.left->data.monadic, (_etype)) ) +// 0 to 8, 0x30 to 0x31 +#define ENODE_CASE_MONADIC \ + case EPOSTINC: \ + case EPOSTDEC: \ + case EPREINC: \ + case EPREDEC: \ + case EINDIRECT: \ + case EMONMIN: \ + case EBINNOT: \ + case ELOGNOT: \ + case EFORCELOAD: \ + case ETYPCON: \ + case EBITFIELD: + +// 9 to 0x1B +#define ENODE_CASE_DIADIC_1 \ + case EMUL: \ + case EMULV: \ + case EDIV: \ + case EMODULO: \ + case EADDV: \ + case ESUBV: \ + case EADD: \ + case ESUB: \ + case ESHL: \ + case ESHR: \ + case ELESS: \ + case EGREATER: \ + case ELESSEQU: \ + case EGREATEREQU: \ + case EEQU: \ + case ENOTEQU: \ + case EAND: \ + case EXOR: \ + case EOR: + +// 0x1E to 0x28, 0x2D, 0x2F +#define ENODE_CASE_ASSIGN \ + case EASS: \ + case EMULASS: \ + case EDIVASS: \ + case EMODASS: \ + case EADDASS: \ + case ESUBASS: \ + case ESHLASS: \ + case ESHRASS: \ + case EANDASS: \ + case EXORASS: \ + case EORASS: \ + case EBCLR: \ + case EBSET: + #ifdef __MWERKS__ #pragma options align=reset #endif diff --git a/includes/compiler/objects.h b/includes/compiler/objects.h index a6a170b..f824923 100644 --- a/includes/compiler/objects.h +++ b/includes/compiler/objects.h @@ -122,9 +122,9 @@ struct Object { UInt8 flags; ExtendedParam *extParam; Object *toc; - void *any; + //void *any; //char reg; // notsure? - //VarRecord *varptr; // notsure? + VarRecord *varptr; // i think? // union starts at 0x24 in v7 union { struct { @@ -168,7 +168,7 @@ struct Object { struct { VarInfo *info; SInt32 uid; - SInt32 offset; + // SInt32 offset; // ??? Object *realObj; } var; struct { @@ -229,12 +229,19 @@ struct VarInfo { // OK! enum { VarInfoFlag1 = 1, // is parameter? - VarInfoFlag2 = 2, - VarInfoFlag4 = 4, + VarInfoFlag2 = 2, // spill related? + VarInfoFlag4 = 4, // 64-bit spill related? VarInfoFlag40 = 0x40, VarInfoFlag80 = 0x80 }; +// placing these here until further notice + +// unknown name, mwcppc.exe 7.0: 484870 +inline Boolean Inline_IsObjectData(Object *object) { + return object->datatype == DDATA; +} + #ifdef __MWERKS__ #pragma options align=reset #endif |