summaryrefslogtreecommitdiff
path: root/includes/compiler/IroLoop.h
blob: 0c605894d61ad1534df5d100f8ee0dd12731caa2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#ifndef COMPILER_IROLOOP_H
#define COMPILER_IROLOOP_H

#include "compiler/IrOptimizer.h"
#include "compiler/BitVector.h"

typedef enum IROLoopIndFlags {
    LoopInd_HasMod = 1,
    LoopInd_HasDiv = 2,
    LoopInd_4 = 4,
    LoopInd_8 = 8
} IROLoopIndFlags;

typedef enum IROLoopFlags {
    LoopFlags_1 = 1, // LP_INDUCTION_AT_LEFT
    LP_LOOP_HAS_CALLS = 2,
    LP_LOOP_HAS_CNTRLFLOW = 4,
    LoopFlags_8 = 8, // LP_HAS_NONASSIGN
    LP_INDUCTION_NOT_FOUND = 0x10,
    LP_IFEXPR_NON_CANONICAL = 0x20,
    LP_HAS_MULTIPLE_INDUCTIONS = 0x40,
    LP_LOOP_HDR_HAS_SIDEEFFECTS = 0x80,
    LP_LOOP_STEP_ISADD = 0x100,
    LoopFlags_200 = 0x200, // LP_HEADER_FOLLOWS_UPDATE?
    LP_LOOP_STEP_ISPOS = 0x400,
    LoopFlags_800 = 0x800, // LP_IND_USED_IN_LOOP
    LoopFlags_1000 = 0x1000, // LP_HAS_MULTIPLE_EXITS
    LoopFlags_2000 = 0x2000, // inverse of LP_LOOP_STEP_ISADD?
    LP_LOOP_STEP_ISNEG = 0x4000,
    LP_LOOP_HAS_ASM = 0x8000,
    LoopFlags_10000 = 0x10000, // LP_WHILE_LOOP
    LoopFlags_20000 = 0x20000, // maybe LP_RECURSIVE_LOOP?
    LoopFlags_40000 = 0x40000 // LP_IS_REDUCTION_CAND
} 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;
    IRONode *xC;
    IRONode *x10;
    IROLinear *nd14; // assignment expression that sets the initial value of induction
    IROLinear *nd18; // ifexpr?
    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