mirror of https://git.wuffs.org/MWCC
2737 lines
79 KiB
C
2737 lines
79 KiB
C
#include "compiler/IroPointerAnalysis.h"
|
|
#include "compiler/IroMalloc.h"
|
|
#include "compiler/CError.h"
|
|
#include "compiler/CInt64.h"
|
|
#include "compiler/CParser.h"
|
|
#include "compiler/objects.h"
|
|
#include "compiler/types.h"
|
|
|
|
// TODO: this should really be elsewhere (but where?)
|
|
CW_INLINE UInt32 gcd(UInt32 a, UInt32 b) {
|
|
UInt32 chk;
|
|
|
|
if (!a)
|
|
return b;
|
|
if (!b)
|
|
return a;
|
|
|
|
while (1) {
|
|
chk = a % b;
|
|
if (!chk)
|
|
return b;
|
|
a = b;
|
|
b = chk;
|
|
}
|
|
}
|
|
|
|
// #define IRO_DEBUG
|
|
|
|
typedef struct ExtendedParamSet ExtendedParamSet;
|
|
typedef struct LocationSet LocationSet;
|
|
typedef struct LocationSetSet LocationSetSet;
|
|
typedef struct ObjectSet ObjectSet;
|
|
typedef struct PAHeapBlock PAHeapBlock;
|
|
typedef struct PALocalVar PALocalVar;
|
|
typedef struct PAMemoryBlock PAMemoryBlock;
|
|
typedef struct ParamMapping ParamMapping;
|
|
typedef struct ParamMappingFunction ParamMappingFunction;
|
|
typedef struct PartialTransferFunction PartialTransferFunction;
|
|
typedef struct PointsToEntry PointsToEntry;
|
|
// typedef struct PointsToFunction PointsToFunction;
|
|
typedef struct Stack Stack;
|
|
typedef struct StackElement StackElement;
|
|
|
|
typedef UInt32 uint32;
|
|
|
|
void __assertion_failed(char *expr, char *filename, int line);
|
|
|
|
#ifdef IRO_DEBUG
|
|
#define IRO_ASSERT(line, expr) \
|
|
do { \
|
|
if (!(expr)) { \
|
|
__assertion_failed(#expr, __FILE__, line); \
|
|
} \
|
|
} while (0);
|
|
|
|
#define IRO_DEBUG_CLEAR(obj, type) \
|
|
memset((obj), 0xFF, sizeof(type))
|
|
#else
|
|
#define IRO_ASSERT(line, expr) ((void) 0)
|
|
#define IRO_DEBUG_CLEAR(obj, type) ((void) 0)
|
|
#endif
|
|
|
|
#ifdef __MWERKS__
|
|
#pragma options align=mac68k
|
|
#endif
|
|
struct StackElement {
|
|
Object *proc;
|
|
PartialTransferFunction *ptf;
|
|
ParamMappingFunction *map;
|
|
IROLinear *funcCall;
|
|
};
|
|
|
|
struct Stack {
|
|
StackElement *top;
|
|
Stack *next;
|
|
};
|
|
|
|
struct ObjectSet {
|
|
Object *proc;
|
|
ObjectSet *otherProcs;
|
|
};
|
|
|
|
struct ExtendedParam {
|
|
ObjectSet *objectSet;
|
|
uint32 x4;
|
|
};
|
|
|
|
struct ExtendedParamSet {
|
|
ExtendedParam *ep;
|
|
ExtendedParamSet *otherEps;
|
|
};
|
|
|
|
struct PAHeapBlock {
|
|
IROLinear *x0;
|
|
};
|
|
|
|
struct PALocalVar {
|
|
Object *x0;
|
|
char *x4;
|
|
};
|
|
|
|
typedef enum {
|
|
PAMEMORYBLOCKKIND_INVALID,
|
|
PAMEMORYBLOCKKIND_1,
|
|
PAMEMORYBLOCKKIND_EXTENDEDPARAM,
|
|
PAMEMORYBLOCKKIND_LOCALVAR,
|
|
PAMEMORYBLOCKKIND_HEAPBLOCK,
|
|
PAMEMORYBLOCKKIND_INT,
|
|
PAMEMORYBLOCKKIND_6
|
|
} PAMemoryBlockKind;
|
|
|
|
struct PAMemoryBlock {
|
|
PAMemoryBlockKind kind;
|
|
union {
|
|
ExtendedParam *ep;
|
|
PALocalVar *localvar;
|
|
PAHeapBlock *heapblock;
|
|
CInt64 intval;
|
|
void *x6;
|
|
} u;
|
|
};
|
|
|
|
struct LocationSet {
|
|
PAMemoryBlock *block;
|
|
Type *rtype;
|
|
union {
|
|
struct {
|
|
CInt64 field;
|
|
UInt32 stride;
|
|
} known;
|
|
struct {
|
|
PAMemoryBlock *restriction;
|
|
LocationSet *bitfieldOf;
|
|
} unknown;
|
|
} u;
|
|
};
|
|
|
|
struct LocationSetSet {
|
|
LocationSet *loc;
|
|
LocationSetSet *otherLocs;
|
|
UInt8 count;
|
|
};
|
|
|
|
struct ParamMapping {
|
|
IROLinear *actual;
|
|
Object *formal;
|
|
ExtendedParam *extended;
|
|
};
|
|
|
|
struct ParamMappingFunction {
|
|
ParamMapping *mapping;
|
|
ParamMappingFunction *otherMappings;
|
|
};
|
|
|
|
struct PointsToEntry {
|
|
LocationSet *loc;
|
|
LocationSetSet *locs;
|
|
};
|
|
|
|
struct PointsToFunction {
|
|
PointsToEntry *pte;
|
|
PointsToFunction *otherPtes;
|
|
};
|
|
|
|
struct PartialTransferFunction {
|
|
PointsToFunction *initialPointsToFn;
|
|
PointsToFunction *finalPointsToFn;
|
|
LocationSetSet *funcModifies;
|
|
LocationSet *returnLocation;
|
|
Boolean x10;
|
|
struct {
|
|
IROLinear *nd;
|
|
PartialTransferFunction *ptf;
|
|
} context;
|
|
};
|
|
|
|
struct PTFList {
|
|
PartialTransferFunction *ptf;
|
|
PTFList *otherPTFs;
|
|
};
|
|
#ifdef __MWERKS__
|
|
#pragma options align=reset
|
|
#endif
|
|
|
|
// TODO: how many of these are actually in IroPointerAnalysis.c?
|
|
static uint32 stExtendedParamNum;
|
|
static PartialTransferFunction *stUnknownPTF;
|
|
static uint32 stIndentationLevel;
|
|
static UInt8 stTabs[0x2C]; // unused mystery object
|
|
static Stack *stCallingContextStack;
|
|
static ObjectList *stParamObjs;
|
|
static jmp_buf stAbortPointerAnalysis;
|
|
static Object stUnknown;
|
|
static Object *stCurrentProc;
|
|
static ExtendedParamSet *stExtParamSet;
|
|
static PTFList *stPTFList;
|
|
static uint32 stMaxPassCount;
|
|
// TODO: stEvalProcActionParams
|
|
static IRONode *stExceptionFNode;
|
|
|
|
static PAMemoryBlock stDummyMemoryBlock = {
|
|
PAMEMORYBLOCKKIND_1
|
|
};
|
|
static PAMemoryBlock *stUnknownMb = &stDummyMemoryBlock;
|
|
|
|
static LocationSet stDummyLocationSet = {
|
|
&stDummyMemoryBlock
|
|
};
|
|
|
|
static LocationSet *stUnknownLs = &stDummyLocationSet;
|
|
|
|
// forward decls
|
|
CW_INLINE StackElement *Stack_sub_48A5B0(Stack **stackPtr);
|
|
CW_INLINE void ObjectSet_RemoveAll(ObjectSet *procList);
|
|
CW_INLINE void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList);
|
|
CW_INLINE void LocationSet_Copy(LocationSet *dest, LocationSet *src);
|
|
CW_INLINE Boolean LocationSet_IsUnknown(LocationSet *ls);
|
|
CW_INLINE void LocationSetSet_RemoveAll(LocationSetSet *lss);
|
|
CW_INLINE void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src);
|
|
CW_INLINE void ParamMappingFunction_RemoveAll(ParamMappingFunction *pmf);
|
|
CW_INLINE void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *dest, ParamMappingFunction *src);
|
|
CW_INLINE void PointsToFunction_RemoveAll(PointsToFunction *pointsToFunc);
|
|
CW_INLINE void PointsToFunction_AddAllIGuess_sub_487D80(PointsToFunction *dest, PointsToFunction *src);
|
|
CW_INLINE void PTFList_RemoveAll(PTFList *ptfList);
|
|
|
|
CW_INLINE StackElement *StackElement_New(void) {
|
|
StackElement *stackElement = IRO_malloc(sizeof(StackElement));
|
|
IRO_ASSERT(103, stackElement != NULL);
|
|
#ifdef IRO_DEBUG
|
|
stackElement->proc = NULL;
|
|
stackElement->ptf = NULL;
|
|
stackElement->map = NULL;
|
|
stackElement->funcCall = NULL;
|
|
#endif
|
|
return stackElement;
|
|
}
|
|
|
|
CW_INLINE void StackElement_Delete(StackElement *stackElement) {
|
|
IRO_ASSERT(117, stackElement != NULL);
|
|
IRO_ASSERT(118, stackElement->proc == NULL);
|
|
IRO_ASSERT(119, stackElement->ptf == NULL);
|
|
IRO_ASSERT(120, stackElement->map == NULL);
|
|
IRO_ASSERT(121, stackElement->funcCall == NULL);
|
|
IRO_DEBUG_CLEAR(stackElement, sizeof(StackElement));
|
|
IRO_free(stackElement);
|
|
}
|
|
|
|
CW_INLINE void StackElement_Init(StackElement *stackElement, Object *proc, PartialTransferFunction *ptf, ParamMappingFunction *map, IROLinear *funcCall) {
|
|
IRO_ASSERT(131, stackElement != NULL);
|
|
IRO_ASSERT(132, proc != NULL);
|
|
IRO_ASSERT(133, ptf != NULL);
|
|
IRO_ASSERT(134, map != NULL);
|
|
IRO_ASSERT(135, funcCall != NULL);
|
|
stackElement->proc = proc;
|
|
stackElement->ptf = ptf;
|
|
stackElement->map = map;
|
|
stackElement->funcCall = funcCall;
|
|
}
|
|
|
|
CW_INLINE void StackElement_Copy(StackElement *dest, StackElement *src) {
|
|
IRO_ASSERT(145, dest != NULL);
|
|
IRO_ASSERT(146, src != NULL);
|
|
StackElement_Init(dest, src->proc, src->ptf, src->map, src->funcCall);
|
|
}
|
|
|
|
CW_INLINE void StackElement_Term(StackElement *stackElement) {
|
|
IRO_ASSERT(156, stackElement != NULL);
|
|
#ifdef IRO_DEBUG
|
|
stackElement->proc = NULL;
|
|
stackElement->ptf = NULL;
|
|
stackElement->map = NULL;
|
|
stackElement->funcCall = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE void *StackElement_sub_48A780(StackElement *stackElement) {
|
|
IRO_ASSERT(213, stackElement != NULL);
|
|
return stackElement->proc;
|
|
}
|
|
|
|
CW_INLINE Boolean StackRelated_sub_48A760(void *key1, void *key2) {
|
|
IRO_ASSERT(220, key1 != NULL);
|
|
IRO_ASSERT(221, key2 != NULL);
|
|
return key1 == key2;
|
|
}
|
|
|
|
CW_INLINE Object *StackElement_proc(StackElement *stackElement) {
|
|
IRO_ASSERT(228, stackElement != NULL);
|
|
return stackElement->proc;
|
|
}
|
|
|
|
CW_INLINE PartialTransferFunction *StackElement_ptf(StackElement *stackElement) {
|
|
IRO_ASSERT(235, stackElement != NULL);
|
|
return stackElement->ptf;
|
|
}
|
|
|
|
CW_INLINE ParamMappingFunction *StackElement_map(StackElement *stackElement) {
|
|
IRO_ASSERT(242, stackElement != NULL);
|
|
return stackElement->map;
|
|
}
|
|
|
|
CW_INLINE IROLinear *StackElement_funcCall(StackElement *stackElement) {
|
|
IRO_ASSERT(249, stackElement != NULL);
|
|
return stackElement->funcCall;
|
|
}
|
|
|
|
CW_INLINE Stack *Stack_New(void) {
|
|
Stack *stack = IRO_malloc(sizeof(Stack));
|
|
IRO_ASSERT(265, stack != NULL);
|
|
#ifdef IRO_DEBUG
|
|
stack->top = NULL;
|
|
stack->next = NULL;
|
|
#endif
|
|
return stack;
|
|
}
|
|
|
|
CW_INLINE void Stack_Delete(Stack *stack) {
|
|
IRO_ASSERT(277, stack != NULL);
|
|
IRO_ASSERT(278, stack->top == NULL);
|
|
IRO_ASSERT(279, stack->next == NULL);
|
|
IRO_DEBUG_CLEAR(stack, sizeof(Stack));
|
|
IRO_free(stack);
|
|
}
|
|
|
|
CW_INLINE void Stack_Init(Stack *stack) {
|
|
IRO_ASSERT(289, stack != NULL);
|
|
stack->top = NULL;
|
|
stack->next = NULL;
|
|
}
|
|
|
|
CW_INLINE void Stack_Term(Stack **stackPtr) {
|
|
StackElement *stackElement;
|
|
|
|
IRO_ASSERT(299, stackPtr != NULL);
|
|
IRO_ASSERT(300, *stackPtr != NULL);
|
|
|
|
while ((*stackPtr)->top) {
|
|
stackElement = Stack_sub_48A5B0(stackPtr);
|
|
StackElement_Term(stackElement);
|
|
StackElement_Delete(stackElement);
|
|
}
|
|
}
|
|
|
|
CW_INLINE void Stack_sub_48A660(Stack **stackPtr, StackElement *stackElement) {
|
|
StackElement *newElement;
|
|
Stack *newStack;
|
|
|
|
IRO_ASSERT(315, stackPtr != NULL);
|
|
IRO_ASSERT(316, *stackPtr != NULL);
|
|
|
|
newElement = StackElement_New();
|
|
StackElement_Copy(newElement, stackElement);
|
|
|
|
newStack = Stack_New();
|
|
newStack->top = newElement;
|
|
newStack->next = *stackPtr;
|
|
*stackPtr = newStack;
|
|
}
|
|
|
|
CW_INLINE StackElement *Stack_Top(Stack **stackPtr) {
|
|
IRO_ASSERT(331, stackPtr != NULL);
|
|
IRO_ASSERT(332, *stackPtr != NULL);
|
|
|
|
return (*stackPtr)->top;
|
|
}
|
|
|
|
CW_INLINE Stack *Stack_Next(Stack **stackPtr) {
|
|
IRO_ASSERT(343, stackPtr != NULL);
|
|
IRO_ASSERT(344, *stackPtr != NULL);
|
|
|
|
return (*stackPtr)->next;
|
|
}
|
|
|
|
CW_INLINE StackElement *Stack_sub_48A5B0(Stack **stackPtr) {
|
|
StackElement *stackElement;
|
|
|
|
IRO_ASSERT(357, stackPtr != NULL);
|
|
IRO_ASSERT(358, *stackPtr != NULL);
|
|
|
|
stackElement = (*stackPtr)->top;
|
|
if (stackElement) {
|
|
Stack *next = (*stackPtr)->next;
|
|
(*stackPtr)->top = NULL;
|
|
(*stackPtr)->next = NULL;
|
|
Stack_Delete(*stackPtr);
|
|
*stackPtr = next;
|
|
}
|
|
|
|
return stackElement;
|
|
}
|
|
|
|
CW_INLINE StackElement *Stack_sub_48A710(Stack **stackPtr, void *key) {
|
|
Stack *stack;
|
|
|
|
IRO_ASSERT(379, stackPtr != NULL);
|
|
IRO_ASSERT(380, key != NULL);
|
|
|
|
for (stack = *stackPtr; stack; stack = stack->next) {
|
|
if (stack->top) {
|
|
if (StackRelated_sub_48A760(StackElement_sub_48A780(stack->top), key))
|
|
return stack->top;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE ObjectSet *ObjectSet_New(void) {
|
|
ObjectSet *procList;
|
|
|
|
procList = IRO_malloc(sizeof(ObjectSet));
|
|
IRO_ASSERT(439, procList != NULL);
|
|
#ifdef IRO_DEBUG
|
|
procList->proc = NULL;
|
|
procList->otherProcs = NULL;
|
|
#endif
|
|
return procList;
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_Delete(ObjectSet *procList) {
|
|
IRO_ASSERT(451, procList != NULL);
|
|
IRO_ASSERT(452, procList->proc == NULL);
|
|
IRO_ASSERT(453, procList->otherProcs == NULL);
|
|
IRO_DEBUG_CLEAR(procList, sizeof(ObjectSet));
|
|
IRO_free(procList);
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_Init(ObjectSet *procList) {
|
|
IRO_ASSERT(463, procList != NULL);
|
|
procList->proc = NULL;
|
|
procList->otherProcs = NULL;
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_Term(ObjectSet *procList) {
|
|
IRO_ASSERT(481, procList != NULL);
|
|
ObjectSet_RemoveAll(procList);
|
|
#ifdef IRO_DEBUG
|
|
procList->proc = NULL;
|
|
procList->otherProcs = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_ForEach(ObjectSet *procList, void (*action)(Object *, void *), void *refcon) {
|
|
IRO_ASSERT(528, procList != NULL);
|
|
IRO_ASSERT(529, action != NULL);
|
|
IRO_ASSERT(530, refcon == NULL || refcon != NULL);
|
|
|
|
while (procList && procList->proc) {
|
|
action(procList->proc, refcon);
|
|
procList = procList->otherProcs;
|
|
}
|
|
}
|
|
|
|
CW_INLINE Object *ObjectSet_sub_485020(ObjectSet *procList, Object *proc) {
|
|
IRO_ASSERT(540, procList != NULL);
|
|
IRO_ASSERT(541, proc != NULL);
|
|
while (procList && procList->proc) {
|
|
if (procList->proc == proc)
|
|
return procList->proc;
|
|
procList = procList->otherProcs;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE Object *ObjectSet_FindFirst(ObjectSet *procList) {
|
|
IRO_ASSERT(552, procList != NULL);
|
|
return procList->proc;
|
|
}
|
|
|
|
CW_INLINE int ObjectSet_Count(ObjectSet *procList) {
|
|
int count;
|
|
|
|
IRO_ASSERT(561, procList != NULL);
|
|
|
|
count = 0;
|
|
while (procList && procList->proc) {
|
|
count++;
|
|
procList = procList->otherProcs;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_sub_486800(ObjectSet *procList, Object *proc) {
|
|
ObjectSet *newProcList;
|
|
|
|
IRO_ASSERT(574, procList != NULL);
|
|
IRO_ASSERT(575, proc != NULL);
|
|
|
|
if (procList->proc) {
|
|
newProcList = ObjectSet_New();
|
|
ObjectSet_Init(newProcList);
|
|
newProcList->proc = procList->proc;
|
|
newProcList->otherProcs = procList->otherProcs;
|
|
procList->otherProcs = newProcList;
|
|
}
|
|
|
|
procList->proc = proc;
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_sub_4867D0(ObjectSet *procList, Object *proc) {
|
|
IRO_ASSERT(592, procList != NULL);
|
|
IRO_ASSERT(593, proc != NULL);
|
|
|
|
if (!ObjectSet_sub_485020(procList, proc))
|
|
ObjectSet_sub_486800(procList, proc);
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_Remove(ObjectSet *procList, Object *proc) {
|
|
ObjectSet *prev;
|
|
ObjectSet *tmp;
|
|
|
|
IRO_ASSERT(605, procList != NULL);
|
|
IRO_ASSERT(606, proc != NULL);
|
|
|
|
prev = NULL;
|
|
while (procList && procList->proc) {
|
|
if (procList->proc == proc) {
|
|
if (!prev) {
|
|
if (procList->otherProcs == NULL) {
|
|
procList->proc = NULL;
|
|
} else {
|
|
tmp = procList->otherProcs;
|
|
procList->proc = procList->otherProcs->proc;
|
|
procList->otherProcs = procList->otherProcs->otherProcs;
|
|
tmp->proc = NULL;
|
|
tmp->otherProcs = NULL;
|
|
ObjectSet_Term(tmp);
|
|
ObjectSet_Delete(tmp);
|
|
}
|
|
} else {
|
|
prev->otherProcs = procList->otherProcs;
|
|
procList->proc = NULL;
|
|
procList->otherProcs = NULL;
|
|
ObjectSet_Term(procList);
|
|
ObjectSet_Delete(procList);
|
|
}
|
|
return;
|
|
}
|
|
prev = procList;
|
|
procList = procList->otherProcs;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_RemoveAll(ObjectSet *procList) {
|
|
IRO_ASSERT(645, procList != NULL);
|
|
|
|
while (procList && procList->proc)
|
|
ObjectSet_Remove(procList, procList->proc);
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_AddSetAction(Object *proc, void *refcon) {
|
|
IRO_ASSERT(655, proc != NULL);
|
|
IRO_ASSERT(656, refcon != NULL);
|
|
|
|
ObjectSet_sub_4867D0(refcon, proc);
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_SimpleAddSetAction(Object *proc, void *refcon) {
|
|
IRO_ASSERT(663, proc != NULL);
|
|
IRO_ASSERT(664, refcon != NULL);
|
|
|
|
ObjectSet_sub_486800(refcon, proc);
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_sub_48C590(ObjectSet *dest, ObjectSet *src) {
|
|
IRO_ASSERT(671, dest != NULL);
|
|
IRO_ASSERT(672, src != NULL);
|
|
|
|
if (dest->proc)
|
|
ObjectSet_ForEach(src, ObjectSet_AddSetAction, dest);
|
|
else
|
|
ObjectSet_ForEach(src, ObjectSet_SimpleAddSetAction, dest);
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_RemoveSetAction(Object *proc, void *refcon) {
|
|
IRO_ASSERT(682, proc != NULL);
|
|
IRO_ASSERT(683, refcon != NULL);
|
|
|
|
ObjectSet_Remove(refcon, proc);
|
|
}
|
|
|
|
CW_INLINE void ObjectSet_removeiter_sub_48C890(ObjectSet *dest, ObjectSet *src) {
|
|
IRO_ASSERT(690, dest != NULL);
|
|
IRO_ASSERT(691, src != NULL);
|
|
|
|
ObjectSet_ForEach(src, ObjectSet_RemoveSetAction, dest);
|
|
}
|
|
|
|
CW_INLINE Boolean ObjectSet_sub_484FA0(ObjectSet *os1, ObjectSet *os2) {
|
|
ObjectSet *scan;
|
|
|
|
IRO_ASSERT(700, os1 != NULL);
|
|
IRO_ASSERT(701, os2 != NULL);
|
|
|
|
if (os1 == os2)
|
|
return 1;
|
|
|
|
for (scan = os1; scan && scan->proc; scan = scan->otherProcs) {
|
|
if (!ObjectSet_sub_485020(os2, scan->proc))
|
|
return 0;
|
|
}
|
|
|
|
for (scan = os2; scan && scan->proc; scan = scan->otherProcs) {
|
|
if (!ObjectSet_sub_485020(os1, scan->proc))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
CW_INLINE ExtendedParam *ExtendedParam_New(void) {
|
|
ExtendedParam *ep = IRO_malloc(sizeof(ExtendedParam));
|
|
|
|
IRO_ASSERT(755, ep != NULL);
|
|
#ifdef IRO_DEBUG
|
|
ep->objectSet = NULL;
|
|
#endif
|
|
return ep;
|
|
}
|
|
|
|
CW_INLINE void ExtendedParam_Delete(ExtendedParam *ep) {
|
|
IRO_ASSERT(762, ep != NULL);
|
|
IRO_ASSERT(763, ep->objectSet == NULL);
|
|
IRO_DEBUG_CLEAR(ep, sizeof(ExtendedParam));
|
|
IRO_free(ep);
|
|
}
|
|
|
|
CW_INLINE void ExtendedParam_Init(ExtendedParam *ep, Object *obj) {
|
|
IRO_ASSERT(777, ep != NULL);
|
|
IRO_ASSERT(778, obj != NULL);
|
|
IRO_ASSERT(779, obj->extParam == NULL);
|
|
IRO_ASSERT(780, stExtendedParamNum < ((uint32) -1) / 2 - 1);
|
|
|
|
ep->objectSet = ObjectSet_New();
|
|
ObjectSet_Init(ep->objectSet);
|
|
ObjectSet_sub_4867D0(ep->objectSet, obj);
|
|
obj->extParam = ep;
|
|
|
|
ep->x4 = stExtendedParamNum++;
|
|
}
|
|
|
|
CW_INLINE void ExtendedParam_TermAction(Object *obj, void *refcon) {
|
|
obj->extParam = NULL;
|
|
}
|
|
|
|
CW_INLINE void ExtendedParam_Term(ExtendedParam *ep) {
|
|
IRO_ASSERT(800, ep != NULL);
|
|
|
|
ObjectSet_ForEach(ep->objectSet, ExtendedParam_TermAction, NULL);
|
|
ObjectSet_Term(ep->objectSet);
|
|
ObjectSet_Delete(ep->objectSet);
|
|
#ifdef IRO_DEBUG
|
|
ep->objectSet = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE Boolean ExtendedParams_Equal(ExtendedParam *ep1, ExtendedParam *ep2) {
|
|
IRO_ASSERT(841, ep1 != NULL);
|
|
IRO_ASSERT(842, ep2 != NULL);
|
|
IRO_ASSERT(843, ep1->objectSet != NULL);
|
|
IRO_ASSERT(844, ep2->objectSet != NULL);
|
|
|
|
if (ep1 == ep2)
|
|
return 1;
|
|
|
|
return ep1->x4 == ep2->x4 && ObjectSet_sub_484FA0(ep1->objectSet, ep2->objectSet);
|
|
}
|
|
|
|
CW_INLINE ExtendedParam *ExtendedParam_FindByObject(Object *obj) {
|
|
IRO_ASSERT(856, obj != NULL);
|
|
|
|
return obj->extParam;
|
|
}
|
|
|
|
CW_INLINE void ExtendedParam_sub_4867B0(ExtendedParam *ep, Object *obj) {
|
|
IRO_ASSERT(863, ep != NULL);
|
|
IRO_ASSERT(864, ep->objectSet != NULL);
|
|
IRO_ASSERT(865, obj != NULL);
|
|
|
|
ObjectSet_sub_4867D0(ep->objectSet, obj);
|
|
obj->extParam = ep;
|
|
}
|
|
|
|
CW_INLINE void ExtendedParam_RemoveObjectSetAction(Object *object, void *refcon) {
|
|
object->extParam = NULL;
|
|
}
|
|
|
|
CW_INLINE void EP_sub_48C850(ExtendedParam *ep, ObjectSet *objSet) {
|
|
IRO_ASSERT(888, ep != NULL);
|
|
IRO_ASSERT(889, ep->objectSet != NULL);
|
|
IRO_ASSERT(890, objSet != NULL);
|
|
|
|
ObjectSet_removeiter_sub_48C890(ep->objectSet, objSet);
|
|
ObjectSet_ForEach(objSet, ExtendedParam_RemoveObjectSetAction, NULL);
|
|
}
|
|
|
|
CW_INLINE ObjectSet *ExtendedParam_objectSet(ExtendedParam *ep) {
|
|
IRO_ASSERT(898, ep != NULL);
|
|
|
|
return ep->objectSet;
|
|
}
|
|
|
|
CW_INLINE uint32 ExtendedParam_sub_489110(ExtendedParam *ep) {
|
|
IRO_ASSERT(905, ep != NULL);
|
|
|
|
return ep->x4;
|
|
}
|
|
|
|
CW_INLINE ExtendedParamSet *AllocsExtParamSet_sub_4876C0(void) {
|
|
ExtendedParamSet *epList = IRO_malloc(sizeof(ExtendedParamSet));
|
|
|
|
IRO_ASSERT(924, epList != NULL);
|
|
#ifdef IRO_DEBUG
|
|
epList->ep = NULL;
|
|
epList->otherEps = NULL;
|
|
#endif
|
|
return epList;
|
|
}
|
|
|
|
CW_INLINE void FreesExtParamSet_sub_48CAE0(ExtendedParamSet *epList) {
|
|
IRO_ASSERT(936, epList != NULL);
|
|
IRO_ASSERT(937, epList->ep == NULL);
|
|
IRO_ASSERT(938, epList->otherEps == NULL);
|
|
IRO_DEBUG_CLEAR(epList, sizeof(ExtendedParamSet));
|
|
IRO_free(epList);
|
|
}
|
|
|
|
CW_INLINE void InitsExtParamSet_sub_4876A0(ExtendedParamSet *epList) {
|
|
IRO_ASSERT(948, epList != NULL);
|
|
epList->ep = NULL;
|
|
epList->otherEps = NULL;
|
|
}
|
|
|
|
CW_INLINE void TermsExtParamSet_sub_48CB00(ExtendedParamSet *epList) {
|
|
IRO_ASSERT(966, epList != NULL);
|
|
ExtendedParamSet_RemoveAll(epList);
|
|
#ifdef IRO_DEBUG
|
|
epList->ep = NULL;
|
|
epList->otherEps = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE void MaybeWalkExtParamSet_sub_48CBE0(ExtendedParamSet *epList, void (*action)(ExtendedParam *, void *), void *refcon) {
|
|
IRO_ASSERT(1010, epList != NULL);
|
|
IRO_ASSERT(1011, action != NULL);
|
|
|
|
while (epList && epList->ep) {
|
|
action(epList->ep, refcon);
|
|
epList = epList->otherEps;
|
|
}
|
|
}
|
|
|
|
CW_INLINE ExtendedParam *ExtParamSet_sub_4876D0(ExtendedParamSet *epList, ExtendedParam *ep) {
|
|
IRO_ASSERT(1022, epList != NULL);
|
|
IRO_ASSERT(1023, ep != NULL);
|
|
|
|
while (epList && epList->ep) {
|
|
if (epList->ep == ep)
|
|
return epList->ep;
|
|
epList = epList->otherEps;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE void ExtParamSet_sub_487660(ExtendedParamSet *epList, ExtendedParam *ep) {
|
|
IRO_ASSERT(1056, epList != NULL);
|
|
IRO_ASSERT(1057, ep != NULL);
|
|
|
|
if (epList->ep) {
|
|
ExtendedParamSet *newSet = AllocsExtParamSet_sub_4876C0();
|
|
InitsExtParamSet_sub_4876A0(newSet);
|
|
newSet->ep = epList->ep;
|
|
newSet->otherEps = epList->otherEps;
|
|
epList->otherEps = newSet;
|
|
}
|
|
|
|
epList->ep = ep;
|
|
}
|
|
|
|
CW_INLINE void ExtParamSet_sub_487630(ExtendedParamSet *epList, ExtendedParam *ep) {
|
|
IRO_ASSERT(1076, epList != NULL);
|
|
IRO_ASSERT(1077, ep != NULL);
|
|
|
|
if (!ExtParamSet_sub_4876D0(epList, ep))
|
|
ExtParamSet_sub_487660(epList, ep);
|
|
}
|
|
|
|
CW_INLINE void ExtendedParamSet_Remove(ExtendedParamSet *epList, ExtendedParam *ep) {
|
|
ExtendedParamSet *prev;
|
|
ExtendedParamSet *tmp;
|
|
|
|
IRO_ASSERT(1089, epList != NULL);
|
|
IRO_ASSERT(1090, ep != NULL);
|
|
|
|
prev = NULL;
|
|
while (epList && epList->ep) {
|
|
if (epList->ep == ep) {
|
|
if (!prev) {
|
|
if (epList->otherEps == NULL) {
|
|
epList->ep = NULL;
|
|
} else {
|
|
tmp = epList->otherEps;
|
|
epList->ep = epList->otherEps->ep;
|
|
epList->otherEps = epList->otherEps->otherEps;
|
|
tmp->ep = NULL;
|
|
tmp->otherEps = NULL;
|
|
TermsExtParamSet_sub_48CB00(tmp);
|
|
FreesExtParamSet_sub_48CAE0(tmp);
|
|
}
|
|
} else {
|
|
prev->otherEps = epList->otherEps;
|
|
epList->ep = NULL;
|
|
epList->otherEps = NULL;
|
|
TermsExtParamSet_sub_48CB00(epList);
|
|
FreesExtParamSet_sub_48CAE0(epList);
|
|
}
|
|
return;
|
|
}
|
|
prev = epList;
|
|
epList = epList->otherEps;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList) {
|
|
IRO_ASSERT(1129, epList != NULL);
|
|
|
|
while (epList && epList->ep)
|
|
ExtendedParamSet_Remove(epList, epList->ep);
|
|
}
|
|
|
|
CW_INLINE PAHeapBlock *CreateUniqueHeapAlloc_sub_486420(void) {
|
|
PAHeapBlock *hb = IRO_malloc(sizeof(PAHeapBlock));
|
|
|
|
IRO_ASSERT(1225, hb != NULL);
|
|
#ifdef IRO_DEBUG
|
|
hb->parent = NULL;
|
|
#endif
|
|
return hb;
|
|
}
|
|
|
|
CW_INLINE void InitUniqueHeapAlloc_sub_486410(PAHeapBlock *hb, IROLinear *nd) {
|
|
IRO_ASSERT(1247, hb != NULL);
|
|
|
|
hb->x0 = nd;
|
|
}
|
|
|
|
CW_INLINE Boolean PAHeapBlocks_Equal(PAHeapBlock *hb1, PAHeapBlock *hb2) {
|
|
IRO_ASSERT(1296, hb1 != NULL);
|
|
IRO_ASSERT(1297, hb2 != NULL);
|
|
|
|
return (hb1 == hb2) || (hb1->x0 == hb2->x0);
|
|
}
|
|
|
|
CW_INLINE PALocalVar *PALocalVar_New(void) {
|
|
PALocalVar *local = IRO_malloc(sizeof(PALocalVar));
|
|
|
|
IRO_ASSERT(1333, local != NULL);
|
|
#ifdef IRO_DEBUG
|
|
local->parent = NULL;
|
|
local->nextSibling = NULL;
|
|
#endif
|
|
return local;
|
|
}
|
|
|
|
CW_INLINE void PALocalVar_InitByObject(PALocalVar *local, Object *obj) {
|
|
IRO_ASSERT(1357, local != NULL);
|
|
IRO_ASSERT(1358, obj != NULL);
|
|
|
|
local->x0 = obj;
|
|
if (obj->name && obj->name->name) {
|
|
local->x4 = IRO_malloc(strlen(obj->name->name) + 1);
|
|
strcpy(local->x4, obj->name->name);
|
|
} else {
|
|
local->x4 = NULL;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void PALocalVar_InitByName(PALocalVar *local, char *name) {
|
|
IRO_ASSERT(1372, local != NULL);
|
|
IRO_ASSERT(1373, name != NULL);
|
|
|
|
local->x0 = NULL;
|
|
local->x4 = IRO_malloc(strlen(name) + 1);
|
|
strcpy(local->x4, name);
|
|
}
|
|
|
|
CW_INLINE Boolean PALocalVars_Equal(PALocalVar *local1, PALocalVar *local2) {
|
|
IRO_ASSERT(1419, local1 == NULL || local1 != NULL);
|
|
IRO_ASSERT(1420, local2 == NULL || local2 != NULL);
|
|
|
|
if (local1 == local2)
|
|
return 1;
|
|
if (!local1 || !local2)
|
|
return 0;
|
|
|
|
if (!local1->x0 || !local2->x0) {
|
|
if (local1->x4)
|
|
return local2->x4 && !strcmp(local1->x4, local2->x4);
|
|
}
|
|
|
|
return local1->x0 == local2->x0;
|
|
}
|
|
|
|
CW_INLINE void PALocalVar_SetSth_sub_4847C0(PALocalVar *local, Object *obj) {
|
|
IRO_ASSERT(1436, local != NULL);
|
|
IRO_ASSERT(1437, obj == NULL || obj != NULL);
|
|
|
|
local->x0 = obj;
|
|
}
|
|
|
|
CW_INLINE Object *PALocalVar_Get0_sub_4847E0(PALocalVar *local) {
|
|
IRO_ASSERT(1444, local != NULL);
|
|
return local->x0;
|
|
}
|
|
|
|
CW_INLINE char *PALocalVar_Get4_sub_4847D0(PALocalVar *local) {
|
|
IRO_ASSERT(1451, local != NULL);
|
|
return local->x4;
|
|
}
|
|
|
|
CW_INLINE PAMemoryBlock *PAMemoryBlock_New(void) {
|
|
PAMemoryBlock *mb = IRO_malloc(sizeof(PAMemoryBlock));
|
|
|
|
IRO_ASSERT(1491, mb != NULL);
|
|
#ifdef IRO_DEBUG
|
|
mb->kind = PAMEMORYBLOCKKIND_INVALID;
|
|
#endif
|
|
return mb;
|
|
}
|
|
|
|
CW_INLINE void PAMemoryBlock_Delete(PAMemoryBlock *mb) {
|
|
IRO_ASSERT(1502, mb != NULL);
|
|
IRO_ASSERT(1503, mb->kind == PAMEMORYBLOCKKIND_INVALID);
|
|
IRO_free(mb);
|
|
}
|
|
|
|
CW_INLINE void PAMemoryBlock_Init(PAMemoryBlock *mb, PAMemoryBlockKind kind, void *thing) {
|
|
IRO_ASSERT(1513, mb != NULL);
|
|
IRO_ASSERT(1514, thing == NULL || thing != NULL);
|
|
|
|
mb->kind = kind;
|
|
switch (mb->kind) {
|
|
case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
|
|
mb->u.ep = (ExtendedParam *) thing;
|
|
break;
|
|
case PAMEMORYBLOCKKIND_LOCALVAR:
|
|
mb->u.localvar = (PALocalVar *) thing;
|
|
break;
|
|
case PAMEMORYBLOCKKIND_HEAPBLOCK:
|
|
mb->u.heapblock = (PAHeapBlock *) thing;
|
|
break;
|
|
case PAMEMORYBLOCKKIND_INT:
|
|
mb->u.intval = *((CInt64 *) thing);
|
|
break;
|
|
case PAMEMORYBLOCKKIND_6:
|
|
mb->u.x6 = (void *) thing;
|
|
break;
|
|
default:
|
|
CError_FATAL(1535);
|
|
}
|
|
}
|
|
|
|
CW_INLINE void PAMemoryBlock_Term(PAMemoryBlock *mb) {
|
|
IRO_ASSERT(1552, mb != NULL);
|
|
|
|
#ifdef IRO_DEBUG
|
|
mb->kind = PAMEMORYBLOCKKIND_INVALID;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE Boolean MemoryBlocks_Equal(PAMemoryBlock *mb1, PAMemoryBlock *mb2) {
|
|
IRO_ASSERT(1657, mb1 == NULL || mb1 != NULL);
|
|
IRO_ASSERT(1658, mb2 == NULL || mb2 != NULL);
|
|
|
|
if (mb1 == mb2)
|
|
return 1;
|
|
|
|
if (!mb1 || !mb2 || mb1->kind != mb2->kind)
|
|
return 0;
|
|
|
|
switch (mb1->kind) {
|
|
case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
|
|
return ExtendedParams_Equal(mb1->u.ep, mb2->u.ep);
|
|
case PAMEMORYBLOCKKIND_LOCALVAR:
|
|
return PALocalVars_Equal(mb1->u.localvar, mb2->u.localvar);
|
|
case PAMEMORYBLOCKKIND_HEAPBLOCK:
|
|
return PAHeapBlocks_Equal(mb1->u.heapblock, mb2->u.heapblock);
|
|
case PAMEMORYBLOCKKIND_INT:
|
|
return CInt64_Equal(mb1->u.intval, mb2->u.intval);
|
|
case PAMEMORYBLOCKKIND_6:
|
|
return mb1->u.x6 == mb2->u.x6;
|
|
default:
|
|
CError_FATAL(1684);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
CW_INLINE PAMemoryBlockKind PAMemoryBlock_kind(PAMemoryBlock *mb) {
|
|
IRO_ASSERT(1692, mb != NULL);
|
|
|
|
return mb->kind;
|
|
}
|
|
|
|
CW_INLINE void *PAMemoryBlock_thing(PAMemoryBlock *mb) {
|
|
IRO_ASSERT(1699, mb != NULL);
|
|
|
|
switch (mb->kind) {
|
|
case PAMEMORYBLOCKKIND_EXTENDEDPARAM:
|
|
return mb->u.ep;
|
|
case PAMEMORYBLOCKKIND_LOCALVAR:
|
|
return mb->u.localvar;
|
|
case PAMEMORYBLOCKKIND_HEAPBLOCK:
|
|
return mb->u.heapblock;
|
|
case PAMEMORYBLOCKKIND_INT:
|
|
return &mb->u.intval;
|
|
case PAMEMORYBLOCKKIND_6:
|
|
return mb->u.x6;
|
|
default:
|
|
CError_FATAL(1719);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
CW_INLINE LocationSet *LocationSet_New(void) {
|
|
LocationSet *ls = IRO_malloc(sizeof(LocationSet));
|
|
|
|
IRO_ASSERT(1767, ls != NULL);
|
|
#ifdef IRO_DEBUG
|
|
ls->block = NULL;
|
|
ls->rtype = NULL;
|
|
ls->u.known.field = cint64_zero;
|
|
ls->u.known.stride = 0;
|
|
#endif
|
|
return ls;
|
|
}
|
|
|
|
CW_INLINE void LocationSet_Delete(LocationSet *ls) {
|
|
IRO_ASSERT(1781, ls != NULL);
|
|
IRO_ASSERT(1782, ls != stUnknownLs);
|
|
IRO_ASSERT(1783, ls->block == NULL);
|
|
IRO_ASSERT(1784, CInt64_IsZero(&ls->u.known.field));
|
|
IRO_ASSERT(1785, ls->u.known.stride == 0);
|
|
IRO_ASSERT(1786, ls->rtype == NULL);
|
|
IRO_DEBUG_CLEAR(ls, sizeof(LocationSet));
|
|
IRO_free(ls);
|
|
}
|
|
|
|
CW_INLINE void LocationSet_InitKnown(LocationSet *ls, PAMemoryBlock *block, CInt64 field, UInt32 stride, Type *rtype) {
|
|
IRO_ASSERT(1796, ls != NULL);
|
|
IRO_ASSERT(1797, ls != stUnknownLs);
|
|
IRO_ASSERT(1798, block != NULL);
|
|
IRO_ASSERT(1799, rtype == NULL || rtype != NULL);
|
|
ls->block = block;
|
|
ls->rtype = rtype;
|
|
ls->u.known.field = field;
|
|
ls->u.known.stride = stride;
|
|
}
|
|
|
|
CW_INLINE void LocationSet_InitUnknown(LocationSet *ls, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) {
|
|
IRO_ASSERT(1809, ls != NULL);
|
|
IRO_ASSERT(1810, ls != stUnknownLs);
|
|
IRO_ASSERT(1811, rtype == NULL || rtype != NULL);
|
|
IRO_ASSERT(1812, restriction == NULL || restriction != NULL);
|
|
IRO_ASSERT(1813, bitfieldOf == NULL || bitfieldOf != NULL);
|
|
|
|
LocationSet_Copy(ls, stUnknownLs);
|
|
ls->rtype = rtype;
|
|
ls->u.unknown.restriction = restriction;
|
|
if (bitfieldOf) {
|
|
ls->u.unknown.bitfieldOf = LocationSet_New();
|
|
LocationSet_Copy(ls->u.unknown.bitfieldOf, bitfieldOf);
|
|
} else {
|
|
ls->u.unknown.bitfieldOf = NULL;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void LocationSet_Copy(LocationSet *dest, LocationSet *src) {
|
|
IRO_ASSERT(1829, src != NULL);
|
|
IRO_ASSERT(1830, dest != NULL);
|
|
|
|
dest->block = src->block;
|
|
dest->rtype = src->rtype;
|
|
|
|
if (!LocationSet_IsUnknown(src)) {
|
|
dest->u.known.field = src->u.known.field;
|
|
dest->u.known.stride = src->u.known.stride;
|
|
} else {
|
|
dest->u.unknown.restriction = src->u.unknown.restriction;
|
|
if (src->u.unknown.bitfieldOf != NULL) {
|
|
dest->u.unknown.bitfieldOf = LocationSet_New();
|
|
LocationSet_Copy(dest->u.unknown.bitfieldOf, src->u.unknown.bitfieldOf);
|
|
} else {
|
|
dest->u.unknown.bitfieldOf = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
CW_INLINE void LocationSet_Term(LocationSet *ls) {
|
|
IRO_ASSERT(1857, ls != NULL);
|
|
IRO_ASSERT(1858, ls != stUnknownLs);
|
|
|
|
#ifdef IRO_DEBUG
|
|
if (LocationSet_IsUnknown(ls) && ls->u.unknown.bitfieldOf) {
|
|
LocationSet_Term(ls->u.unknown.bitfieldOf);
|
|
LocationSet_Delete(ls->u.unknown.bitfieldOf);
|
|
}
|
|
ls->block = NULL;
|
|
ls->rtype = NULL;
|
|
ls->u.known.field = cint64_zero;
|
|
ls->u.known.stride = 0;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE Boolean LocationSets_Overlap(LocationSet *ls1, Type *rtype1, LocationSet *ls2, Type *rtype2) {
|
|
Boolean isUnknown1, isUnknown2;
|
|
PAMemoryBlock *restriction1, *restriction2;
|
|
|
|
IRO_ASSERT(1974, ls1 != NULL);
|
|
IRO_ASSERT(1975, rtype1 == NULL || rtype1 != NULL);
|
|
IRO_ASSERT(1976, ls2 != NULL);
|
|
IRO_ASSERT(1977, rtype2 == NULL || rtype2 != NULL);
|
|
|
|
if (ls1 == ls2)
|
|
return 1;
|
|
|
|
isUnknown1 = LocationSet_IsUnknown(ls1);
|
|
if (isUnknown1)
|
|
restriction1 = ls1->u.unknown.restriction;
|
|
else
|
|
restriction1 = NULL;
|
|
|
|
isUnknown2 = LocationSet_IsUnknown(ls2);
|
|
if (isUnknown2)
|
|
restriction2 = ls2->u.unknown.restriction;
|
|
else
|
|
restriction2 = NULL;
|
|
|
|
if (
|
|
(isUnknown1 && !restriction1) ||
|
|
(isUnknown2 && !restriction2) ||
|
|
(isUnknown1 && isUnknown2 && MemoryBlocks_Equal(restriction1, restriction2))
|
|
)
|
|
return 1;
|
|
|
|
if (isUnknown1 || isUnknown2)
|
|
return 0;
|
|
|
|
if (MemoryBlocks_Equal(ls1->block, ls2->block)) {
|
|
UInt32 size1;
|
|
UInt32 size2;
|
|
UInt32 i;
|
|
CInt64 work;
|
|
CInt64 longgcd;
|
|
|
|
if (rtype1)
|
|
size1 = rtype1->size;
|
|
else
|
|
size1 = -1;
|
|
|
|
if (rtype2)
|
|
size2 = rtype2->size;
|
|
else
|
|
size2 = -1;
|
|
|
|
if (ls1->u.known.stride == ls2->u.known.stride) {
|
|
CInt64 longsize1;
|
|
CInt64 longsize2;
|
|
CInt64_SetULong(&longsize1, size1);
|
|
CInt64_SetULong(&longsize2, size2);
|
|
|
|
return CInt64_Equal(ls1->u.known.field, ls2->u.known.field) ||
|
|
(CInt64_Less(ls1->u.known.field, ls2->u.known.field) && CInt64_Greater(CInt64_Add(ls1->u.known.field, longsize1), ls2->u.known.field)) ||
|
|
(CInt64_Less(ls2->u.known.field, ls1->u.known.field) && CInt64_Greater(CInt64_Add(ls2->u.known.field, longsize2), ls1->u.known.field));
|
|
} else {
|
|
work = CInt64_Sub(ls1->u.known.field, ls2->u.known.field);
|
|
if (CInt64_IsNegative(&work))
|
|
work = CInt64_Neg(work);
|
|
|
|
CInt64_SetULong(&longgcd, gcd(ls1->u.known.stride, ls2->u.known.stride));
|
|
if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero))
|
|
return 1;
|
|
|
|
if (size1 == -1)
|
|
return 1;
|
|
|
|
for (i = 1; i < size1; i++) {
|
|
CInt64_SetLong(&work, i);
|
|
work = CInt64_Add(work, ls1->u.known.field);
|
|
work = CInt64_Sub(work, ls2->u.known.field);
|
|
if (CInt64_IsNegative(&work))
|
|
work = CInt64_Neg(work);
|
|
if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero))
|
|
return 1;
|
|
}
|
|
|
|
if (size2 == -1)
|
|
return 1;
|
|
|
|
for (i = 1; i < size2; i++) {
|
|
CInt64_SetLong(&work, i);
|
|
work = CInt64_Add(work, ls2->u.known.field);
|
|
work = CInt64_Sub(work, ls1->u.known.field);
|
|
if (CInt64_IsNegative(&work))
|
|
work = CInt64_Neg(work);
|
|
if (CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
CW_INLINE Boolean LocationSets_Equal(LocationSet *ls1, LocationSet *ls2) {
|
|
IRO_ASSERT(2080, ls1 != NULL);
|
|
IRO_ASSERT(2081, ls2 != NULL);
|
|
|
|
return
|
|
(ls1 == ls2) ||
|
|
(
|
|
(LocationSet_IsUnknown(ls1) && LocationSet_IsUnknown(ls2)) &&
|
|
(MemoryBlocks_Equal(ls1->u.unknown.restriction, ls2->u.unknown.restriction)) &&
|
|
((ls1->u.unknown.bitfieldOf == ls2->u.unknown.bitfieldOf) ||
|
|
(ls1->u.unknown.bitfieldOf && ls2->u.unknown.bitfieldOf && LocationSets_Equal(ls1->u.unknown.bitfieldOf, ls2->u.unknown.bitfieldOf))) &&
|
|
((ls1->rtype == ls2->rtype) || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size))
|
|
) ||
|
|
(
|
|
(!LocationSet_IsUnknown(ls1) && !LocationSet_IsUnknown(ls2)) &&
|
|
(ls1->u.known.stride == ls2->u.known.stride) &&
|
|
((ls1->rtype == ls2->rtype) || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size)) &&
|
|
CInt64_Equal(ls1->u.known.field, ls2->u.known.field) &&
|
|
MemoryBlocks_Equal(ls1->block, ls2->block)
|
|
);
|
|
}
|
|
|
|
CW_INLINE Boolean LocationSets_LookupCompatible(LocationSet *ls1, LocationSet *ls2) {
|
|
IRO_ASSERT(2119, ls1 != NULL);
|
|
IRO_ASSERT(2120, ls2 != NULL);
|
|
|
|
if (
|
|
(ls1 == ls2) ||
|
|
(
|
|
LocationSet_IsUnknown(ls1) &&
|
|
LocationSet_IsUnknown(ls2) &&
|
|
MemoryBlocks_Equal(ls1->u.unknown.restriction, ls2->u.unknown.restriction) &&
|
|
(ls1->rtype == ls2->rtype || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size))
|
|
))
|
|
return 1;
|
|
|
|
if (
|
|
(!LocationSet_IsUnknown(ls1) && !LocationSet_IsUnknown(ls2)) &&
|
|
(ls1->rtype == ls2->rtype || (ls1->rtype && ls2->rtype && ls1->rtype->size == ls2->rtype->size)) &&
|
|
MemoryBlocks_Equal(ls1->block, ls2->block)
|
|
) {
|
|
CInt64 work;
|
|
CInt64 longgcd;
|
|
|
|
if (ls1->u.known.stride == ls2->u.known.stride)
|
|
return CInt64_Equal(ls1->u.known.field, ls2->u.known.field);
|
|
|
|
work = CInt64_Sub(ls1->u.known.field, ls2->u.known.field);
|
|
if (CInt64_IsNegative(&work))
|
|
work = CInt64_Neg(work);
|
|
|
|
CInt64_SetULong(&longgcd, gcd(ls1->u.known.stride, ls2->u.known.stride));
|
|
return CInt64_Equal(CInt64_ModU(work, longgcd), cint64_zero);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
CW_INLINE Boolean LocationSet_Contains(LocationSet *ls1, Type *rtype1, LocationSet *ls2, Type *rtype2) {
|
|
Boolean unknown1;
|
|
Boolean unknown2;
|
|
PAMemoryBlock *restriction2;
|
|
PAMemoryBlock *restriction1;
|
|
CInt64 longsize1;
|
|
CInt64 longsize2;
|
|
|
|
IRO_ASSERT(2168, ls1 != NULL);
|
|
IRO_ASSERT(2169, ls2 != NULL);
|
|
IRO_ASSERT(2170, rtype1 != NULL);
|
|
IRO_ASSERT(2171, rtype2 != NULL);
|
|
|
|
if (ls1 == ls2)
|
|
return 1;
|
|
|
|
unknown1 = LocationSet_IsUnknown(ls1);
|
|
if (unknown1)
|
|
restriction1 = ls1->u.unknown.restriction;
|
|
else
|
|
restriction1 = NULL;
|
|
|
|
unknown2 = LocationSet_IsUnknown(ls2);
|
|
if (unknown2)
|
|
restriction2 = ls2->u.unknown.restriction;
|
|
else
|
|
restriction2 = NULL;
|
|
|
|
if (unknown1)
|
|
return !restriction1 || (unknown2 && MemoryBlocks_Equal(restriction2, restriction1));
|
|
|
|
CInt64_SetULong(&longsize1, rtype1->size);
|
|
CInt64_SetULong(&longsize2, rtype2->size);
|
|
|
|
return
|
|
!LocationSet_IsUnknown(ls2) &&
|
|
(ls1->u.known.stride == 0) &&
|
|
(ls2->u.known.stride == 0) &&
|
|
rtype1->size >= rtype2->size &&
|
|
CInt64_LessEqual(ls1->u.known.field, ls2->u.known.field) &&
|
|
CInt64_GreaterEqual(CInt64_Add(ls1->u.known.field, longsize1), CInt64_Add(ls2->u.known.field, longsize2)) &&
|
|
MemoryBlocks_Equal(ls1->block, ls2->block);
|
|
}
|
|
|
|
CW_INLINE Boolean LocationSet_IsUnknown(LocationSet *ls) {
|
|
IRO_ASSERT(2233, ls != NULL);
|
|
|
|
return (ls == stUnknownLs) || (ls->block == stUnknownMb);
|
|
}
|
|
|
|
CW_INLINE Boolean LocationSet_sub_48AF30(LocationSet *ls) {
|
|
return
|
|
!LocationSet_IsUnknown(ls) &&
|
|
(ls->u.known.stride == 0) &&
|
|
CInt64_IsZero(&ls->u.known.field) &&
|
|
PAMemoryBlock_kind(ls->block) == PAMEMORYBLOCKKIND_LOCALVAR &&
|
|
!PAMemoryBlock_thing(ls->block);
|
|
}
|
|
|
|
CW_INLINE void LocationSet_SetRtype(LocationSet *ls, Type *rtype) {
|
|
IRO_ASSERT(2263, ls != NULL);
|
|
IRO_ASSERT(2264, ls != stUnknownLs);
|
|
IRO_ASSERT(2265, rtype != NULL);
|
|
|
|
ls->rtype = rtype;
|
|
}
|
|
|
|
CW_INLINE void SetsLocationSetField_sub_4851B0(LocationSet *ls, CInt64 field) {
|
|
IRO_ASSERT(2272, ls != NULL);
|
|
IRO_ASSERT(2273, !LocationSet_IsUnknown(ls));
|
|
|
|
ls->u.known.field = field;
|
|
}
|
|
|
|
CW_INLINE void SetsLocationSetStride_sub_4852D0(LocationSet *ls, SInt32 stride) {
|
|
IRO_ASSERT(2280, ls != NULL);
|
|
IRO_ASSERT(2281, !LocationSet_IsUnknown(ls));
|
|
|
|
ls->u.known.stride = stride;
|
|
}
|
|
|
|
CW_INLINE PAMemoryBlock *LocationSet_block(LocationSet *ls) {
|
|
IRO_ASSERT(2298, ls != NULL);
|
|
|
|
return ls->block;
|
|
}
|
|
|
|
CW_INLINE Type *LocationSet_rtype(LocationSet *ls) {
|
|
IRO_ASSERT(2306, ls != NULL);
|
|
IRO_ASSERT(2307, ls != stUnknownLs);
|
|
|
|
return ls->rtype;
|
|
}
|
|
|
|
CW_INLINE CInt64 LocationSet_field(LocationSet *ls) {
|
|
IRO_ASSERT(2314, ls != NULL);
|
|
IRO_ASSERT(2315, !LocationSet_IsUnknown(ls));
|
|
|
|
return ls->u.known.field;
|
|
}
|
|
|
|
CW_INLINE UInt32 LocationSet_stride(LocationSet *ls) {
|
|
IRO_ASSERT(2322, ls != NULL);
|
|
IRO_ASSERT(2323, !LocationSet_IsUnknown(ls));
|
|
|
|
return ls->u.known.stride;
|
|
}
|
|
|
|
CW_INLINE PAMemoryBlock *LocationSet_restriction(LocationSet *ls) {
|
|
IRO_ASSERT(2330, ls != NULL);
|
|
IRO_ASSERT(2331, LocationSet_IsUnknown(ls));
|
|
|
|
return ls->u.unknown.restriction;
|
|
}
|
|
|
|
CW_INLINE LocationSet *LocationSet_bitfieldOf(LocationSet *ls) {
|
|
IRO_ASSERT(2338, ls != NULL);
|
|
IRO_ASSERT(2339, LocationSet_IsUnknown(ls));
|
|
|
|
return ls->u.unknown.bitfieldOf;
|
|
}
|
|
|
|
CW_INLINE LocationSetSet *LocationSetSet_New(void) {
|
|
LocationSetSet *lss = IRO_malloc(sizeof(LocationSetSet));
|
|
|
|
IRO_ASSERT(2356, lss != NULL);
|
|
#ifdef IRO_DEBUG
|
|
lss->loc = NULL;
|
|
lss->otherLocs = NULL;
|
|
lss->count = 0;
|
|
#endif
|
|
return lss;
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_Delete(LocationSetSet *lss) {
|
|
IRO_ASSERT(2369, lss != NULL);
|
|
IRO_ASSERT(2370, lss->loc == NULL);
|
|
IRO_ASSERT(2371, lss->otherLocs == NULL);
|
|
IRO_ASSERT(2372, lss->count == 0);
|
|
IRO_DEBUG_CLEAR(lss, sizeof(LocationSetSet));
|
|
IRO_free(lss);
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_Init(LocationSetSet *lss) {
|
|
IRO_ASSERT(2382, lss != NULL);
|
|
|
|
lss->loc = NULL;
|
|
lss->otherLocs = NULL;
|
|
lss->count = 0;
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_Copy(LocationSetSet *dest, LocationSetSet *src) {
|
|
IRO_ASSERT(2391, dest != NULL);
|
|
IRO_ASSERT(2392, src != NULL);
|
|
|
|
dest->loc = NULL;
|
|
dest->otherLocs = NULL;
|
|
dest->count = 0;
|
|
LocationSetSet_AddSet(dest, src);
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_Term(LocationSetSet *lss) {
|
|
IRO_ASSERT(2402, lss != NULL);
|
|
|
|
LocationSetSet_RemoveAll(lss);
|
|
|
|
#ifdef IRO_DEBUG
|
|
lss->loc = NULL;
|
|
lss->otherLocs = NULL;
|
|
lss->count = 0;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_ForEach(LocationSetSet *lss, void (*action)(LocationSet *, void *), void *refcon) {
|
|
IRO_ASSERT(2446, lss != NULL);
|
|
IRO_ASSERT(2447, action != NULL);
|
|
IRO_ASSERT(2448, refcon == NULL || refcon != NULL);
|
|
|
|
while (lss && lss->loc) {
|
|
action(lss->loc, refcon);
|
|
lss = lss->otherLocs;
|
|
}
|
|
}
|
|
|
|
CW_INLINE LocationSet *LocationSetSet_Find(LocationSetSet *lss, LocationSet *ls) {
|
|
IRO_ASSERT(2458, lss != NULL);
|
|
IRO_ASSERT(2459, ls != NULL);
|
|
|
|
while (lss && lss->loc) {
|
|
if (LocationSets_Equal(lss->loc, ls))
|
|
return lss->loc;
|
|
lss = lss->otherLocs;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE LocationSet *LocationSetSet_FindUnknown(LocationSetSet *lss) {
|
|
IRO_ASSERT(2470, lss != NULL);
|
|
|
|
if (!lss->loc)
|
|
return stUnknownLs;
|
|
|
|
while (lss && lss->loc) {
|
|
if (LocationSet_IsUnknown(lss->loc))
|
|
return lss->loc;
|
|
lss = lss->otherLocs;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE LocationSet *LocationSetSet_FindFirst(LocationSetSet *lss) {
|
|
IRO_ASSERT(2498, lss != NULL);
|
|
|
|
return lss->loc;
|
|
}
|
|
|
|
CW_INLINE int LocationSetSet_Count(LocationSetSet *lss) {
|
|
IRO_ASSERT(2505, lss != NULL);
|
|
|
|
return lss->count;
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_RemoveAllWithMemoryBlock(LocationSetSet *lss, PAMemoryBlock *block) {
|
|
LocationSetSet *first;
|
|
LocationSetSet *prev;
|
|
LocationSetSet *next;
|
|
LocationSetSet *tmp;
|
|
|
|
IRO_ASSERT(2514, lss != NULL);
|
|
IRO_ASSERT(2515, block != NULL);
|
|
|
|
first = lss;
|
|
prev = NULL;
|
|
while (lss && lss->loc) {
|
|
next = lss->otherLocs;
|
|
if (MemoryBlocks_Equal(block, lss->loc->block)) {
|
|
if (lss->loc != stUnknownLs) {
|
|
LocationSet_Term(lss->loc);
|
|
LocationSet_Delete(lss->loc);
|
|
}
|
|
if (!prev) {
|
|
if (lss->otherLocs == NULL) {
|
|
lss->loc = NULL;
|
|
prev = lss;
|
|
} else {
|
|
tmp = lss->otherLocs;
|
|
lss->loc = lss->otherLocs->loc;
|
|
lss->otherLocs = lss->otherLocs->otherLocs;
|
|
tmp->loc = NULL;
|
|
tmp->otherLocs = NULL;
|
|
LocationSetSet_Term(tmp);
|
|
LocationSetSet_Delete(tmp);
|
|
prev = NULL;
|
|
next = lss;
|
|
}
|
|
} else {
|
|
prev->otherLocs = lss->otherLocs;
|
|
lss->loc = NULL;
|
|
lss->otherLocs = NULL;
|
|
LocationSetSet_Term(lss);
|
|
LocationSetSet_Delete(lss);
|
|
prev = lss;
|
|
}
|
|
first->count--;
|
|
}
|
|
lss = next;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_SimpleAdd(LocationSetSet *lss, LocationSet *ls) {
|
|
IRO_ASSERT(2572, lss != NULL);
|
|
IRO_ASSERT(2573, ls != NULL);
|
|
|
|
if (!LocationSet_IsUnknown(ls) && lss->count < 4) {
|
|
LocationSet *ls2;
|
|
|
|
if (ls == stUnknownLs) {
|
|
ls2 = stUnknownLs;
|
|
} else {
|
|
ls2 = LocationSet_New();
|
|
LocationSet_Copy(ls2, ls);
|
|
}
|
|
|
|
if (lss->loc) {
|
|
LocationSetSet *lss2 = LocationSetSet_New();
|
|
LocationSetSet_Init(lss2);
|
|
lss2->loc = lss->loc;
|
|
lss2->otherLocs = lss->otherLocs;
|
|
lss->otherLocs = lss2;
|
|
}
|
|
|
|
lss->loc = ls2;
|
|
lss->count++;
|
|
} else {
|
|
LocationSet *ls2;
|
|
|
|
LocationSetSet_RemoveAll(lss);
|
|
ls2 = LocationSet_New();
|
|
if (LocationSet_IsUnknown(ls)) {
|
|
LocationSet_Copy(ls2, ls);
|
|
} else {
|
|
LocationSet_Copy(ls2, stUnknownLs);
|
|
if (ls->rtype)
|
|
LocationSet_SetRtype(ls2, ls->rtype);
|
|
}
|
|
|
|
lss->loc = ls2;
|
|
lss->count = 1;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_Add(LocationSetSet *lss, LocationSet *ls) {
|
|
IRO_ASSERT(2622, lss != NULL);
|
|
IRO_ASSERT(2623, ls != NULL);
|
|
|
|
if (!lss->loc || (!LocationSet_IsUnknown(lss->loc) && !LocationSetSet_Find(lss, ls))) {
|
|
if (!LocationSet_IsUnknown(ls) && ls->u.known.stride)
|
|
LocationSetSet_RemoveAllWithMemoryBlock(lss, ls->block);
|
|
LocationSetSet_SimpleAdd(lss, ls);
|
|
}
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_AddUnknown(LocationSetSet *lss, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) {
|
|
LocationSet *ls;
|
|
|
|
IRO_ASSERT(2643, lss != NULL);
|
|
IRO_ASSERT(2644, rtype == NULL || rtype != NULL);
|
|
IRO_ASSERT(2645, restriction == NULL || restriction != NULL);
|
|
IRO_ASSERT(2646, bitfieldOf == NULL || bitfieldOf != NULL);
|
|
|
|
ls = LocationSet_New();
|
|
LocationSet_InitUnknown(ls, rtype, restriction, bitfieldOf);
|
|
LocationSetSet_Add(lss, ls);
|
|
LocationSet_Term(ls);
|
|
LocationSet_Delete(ls);
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_Remove(LocationSetSet *lss, LocationSet *ls) {
|
|
LocationSetSet *prev;
|
|
LocationSetSet *first;
|
|
LocationSetSet *tmp;
|
|
|
|
IRO_ASSERT(2659, lss != NULL);
|
|
IRO_ASSERT(2660, ls != NULL);
|
|
|
|
first = lss;
|
|
prev = NULL;
|
|
while (lss && lss->loc) {
|
|
if (LocationSets_Equal(lss->loc, ls)) {
|
|
if (lss->loc != stUnknownLs) {
|
|
LocationSet_Term(lss->loc);
|
|
LocationSet_Delete(lss->loc);
|
|
}
|
|
if (!prev) {
|
|
if (lss->otherLocs == NULL) {
|
|
lss->loc = NULL;
|
|
} else {
|
|
tmp = lss->otherLocs;
|
|
lss->loc = lss->otherLocs->loc;
|
|
lss->otherLocs = lss->otherLocs->otherLocs;
|
|
tmp->loc = NULL;
|
|
tmp->otherLocs = NULL;
|
|
LocationSetSet_Term(tmp);
|
|
LocationSetSet_Delete(tmp);
|
|
}
|
|
} else {
|
|
prev->otherLocs = lss->otherLocs;
|
|
lss->loc = NULL;
|
|
lss->otherLocs = NULL;
|
|
LocationSetSet_Term(lss);
|
|
LocationSetSet_Delete(lss);
|
|
}
|
|
first->count--;
|
|
return;
|
|
}
|
|
|
|
prev = lss;
|
|
lss = lss->otherLocs;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_RemoveAll(LocationSetSet *lss) {
|
|
IRO_ASSERT(2707, lss != NULL);
|
|
|
|
while (lss && lss->loc)
|
|
LocationSetSet_Remove(lss, lss->loc);
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_AddSetAction(LocationSet *ls, void *refcon) {
|
|
IRO_ASSERT(2717, ls != NULL);
|
|
IRO_ASSERT(2718, refcon != NULL);
|
|
|
|
LocationSetSet_Add((LocationSetSet *) refcon, ls);
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_SimpleAddSetAction(LocationSet *ls, void *refcon) {
|
|
IRO_ASSERT(2725, ls != NULL);
|
|
IRO_ASSERT(2726, refcon != NULL);
|
|
|
|
LocationSetSet_SimpleAdd((LocationSetSet *) refcon, ls);
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src) {
|
|
IRO_ASSERT(2733, dest != NULL);
|
|
IRO_ASSERT(2734, src != NULL);
|
|
|
|
if (dest->count)
|
|
LocationSetSet_ForEach(src, LocationSetSet_AddSetAction, dest);
|
|
else
|
|
LocationSetSet_ForEach(src, LocationSetSet_SimpleAddSetAction, dest);
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_RemoveSetAction(LocationSet *ls, void *refcon) {
|
|
IRO_ASSERT(2744, ls != NULL);
|
|
IRO_ASSERT(2745, refcon != NULL);
|
|
|
|
LocationSetSet_Remove((LocationSetSet *) refcon, ls);
|
|
}
|
|
|
|
CW_INLINE void LocationSetSet_sub_488700(LocationSetSet *dest, LocationSetSet *src) {
|
|
IRO_ASSERT(2752, dest != NULL);
|
|
IRO_ASSERT(2753, src != NULL);
|
|
|
|
LocationSetSet_ForEach(src, LocationSetSet_RemoveSetAction, dest);
|
|
}
|
|
|
|
CW_INLINE Boolean LocationSetSets_Equal(LocationSetSet *lss1, LocationSetSet *lss2) {
|
|
IRO_ASSERT(2826, lss1 != NULL);
|
|
IRO_ASSERT(2827, lss2 != NULL);
|
|
|
|
if (lss1 == lss2)
|
|
return 1;
|
|
if (LocationSetSet_Count(lss1) != LocationSetSet_Count(lss2))
|
|
return 0;
|
|
|
|
while (lss1 && lss1->loc) {
|
|
if (!LocationSetSet_Find(lss2, lss1->loc))
|
|
return 0;
|
|
lss1 = lss1->otherLocs;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
CW_INLINE ParamMapping *ParamMapping_New(void) {
|
|
ParamMapping *pm = IRO_malloc(sizeof(ParamMapping));
|
|
|
|
IRO_ASSERT(2885, pm != NULL);
|
|
#ifdef IRO_DEBUG
|
|
pm->actual = NULL;
|
|
pm->formal = NULL;
|
|
pm->extended = NULL;
|
|
#endif
|
|
return pm;
|
|
}
|
|
|
|
CW_INLINE void ParamMapping_Delete(ParamMapping *pm) {
|
|
IRO_ASSERT(2898, pm != NULL);
|
|
IRO_ASSERT(2899, pm->actual == NULL);
|
|
IRO_ASSERT(2900, pm->formal == NULL);
|
|
IRO_ASSERT(2901, pm->extended == NULL);
|
|
IRO_DEBUG_CLEAR(pm, sizeof(ParamMapping));
|
|
IRO_free(pm);
|
|
}
|
|
|
|
CW_INLINE void ParamMapping_Init_PROBABLY(ParamMapping *pm, IROLinear *actual, Object *formal, ExtendedParam *extended) {
|
|
IRO_ASSERT(2911, pm != NULL);
|
|
|
|
pm->actual = actual;
|
|
pm->formal = formal;
|
|
pm->extended = extended;
|
|
}
|
|
|
|
CW_INLINE void ParamMapping_Copy(ParamMapping *dest, ParamMapping *src) {
|
|
IRO_ASSERT(2920, src != NULL);
|
|
IRO_ASSERT(2921, dest != NULL);
|
|
|
|
dest->actual = src->actual;
|
|
dest->formal = src->formal;
|
|
dest->extended = src->extended;
|
|
}
|
|
|
|
CW_INLINE void ParamMapping_Term(ParamMapping *pm) {
|
|
IRO_ASSERT(2933, pm != NULL);
|
|
|
|
#ifdef IRO_DEBUG
|
|
pm->actual = NULL;
|
|
pm->formal = NULL;
|
|
pm->extended = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE void ParamMapping_SetExtended(ParamMapping *pm, ExtendedParam *ep) {
|
|
IRO_ASSERT(2992, pm != NULL);
|
|
|
|
pm->extended = ep;
|
|
}
|
|
|
|
CW_INLINE IROLinear *ParamMapping_actual(ParamMapping *pm) {
|
|
IRO_ASSERT(2999, pm != NULL);
|
|
|
|
return pm->actual;
|
|
}
|
|
|
|
CW_INLINE ExtendedParam *ParamMapping_extended(ParamMapping *pm) {
|
|
IRO_ASSERT(3011, pm != NULL);
|
|
|
|
return pm->extended;
|
|
}
|
|
|
|
CW_INLINE ParamMappingFunction *ParamMappingFunction_New(void) {
|
|
ParamMappingFunction *pmf = IRO_malloc(sizeof(ParamMappingFunction));
|
|
|
|
IRO_ASSERT(3026, pmf != NULL);
|
|
#ifdef IRO_DEBUG
|
|
pmf->mapping = NULL;
|
|
pmf->otherMappings = NULL;
|
|
#endif
|
|
return pmf;
|
|
}
|
|
|
|
CW_INLINE void ParamMappingFunction_Delete(ParamMappingFunction *pmf) {
|
|
IRO_ASSERT(3039, pmf != NULL);
|
|
IRO_ASSERT(3040, pmf->mapping == NULL);
|
|
IRO_ASSERT(3041, pmf->otherMappings == NULL);
|
|
IRO_DEBUG_CLEAR(pmf, sizeof(ParamMappingFunction));
|
|
IRO_free(pmf);
|
|
}
|
|
|
|
CW_INLINE void ParamMappingFunction_Init(ParamMappingFunction *pmf) {
|
|
IRO_ASSERT(3050, pmf != NULL);
|
|
|
|
pmf->mapping = NULL;
|
|
pmf->otherMappings = NULL;
|
|
}
|
|
|
|
CW_INLINE void ParamMappingFunction_Copy(ParamMappingFunction *dest, ParamMappingFunction *src) {
|
|
IRO_ASSERT(3058, src != NULL);
|
|
IRO_ASSERT(3059, dest != NULL);
|
|
|
|
dest->mapping = NULL;
|
|
dest->otherMappings = NULL;
|
|
ParamMappingFunction_AddAllMaybe_sub_487C50(dest, src);
|
|
}
|
|
|
|
CW_INLINE void ParamMappingFunction_Term(ParamMappingFunction *pmf) {
|
|
IRO_ASSERT(3068, pmf != NULL);
|
|
|
|
ParamMappingFunction_RemoveAll(pmf);
|
|
|
|
#ifdef IRO_DEBUG
|
|
pmf->mapping = NULL;
|
|
pmf->otherMappings = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE void pmf_sub_487C70(ParamMappingFunction *pmf, void (*action)(ParamMapping *, void *), void *refcon) {
|
|
IRO_ASSERT(3111, pmf != NULL);
|
|
IRO_ASSERT(3112, action != NULL);
|
|
IRO_ASSERT(3113, refcon == NULL || refcon != NULL);
|
|
|
|
while (pmf && pmf->mapping) {
|
|
action(pmf->mapping, refcon);
|
|
pmf = pmf->otherMappings;
|
|
}
|
|
}
|
|
|
|
CW_INLINE ParamMapping *ParamMappingFunction_FindMappingByFormal(ParamMappingFunction *pmf, Object *formal) {
|
|
IRO_ASSERT(3123, pmf != NULL);
|
|
IRO_ASSERT(3124, formal != NULL);
|
|
|
|
while (pmf && pmf->mapping) {
|
|
if (pmf->mapping->formal == formal)
|
|
return pmf->mapping;
|
|
pmf = pmf->otherMappings;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE void Pmf_Add_sub_486610(ParamMappingFunction *pmf, ParamMapping *mapping) {
|
|
ParamMapping *existing;
|
|
|
|
IRO_ASSERT(3138, pmf != NULL);
|
|
IRO_ASSERT(3139, mapping != NULL);
|
|
|
|
existing = ParamMappingFunction_FindMappingByFormal(pmf, mapping->formal);
|
|
if (!existing) {
|
|
existing = ParamMapping_New();
|
|
ParamMapping_Copy(existing, mapping);
|
|
if (pmf->mapping) {
|
|
ParamMappingFunction *newPMF = ParamMappingFunction_New();
|
|
ParamMappingFunction_Init(newPMF);
|
|
newPMF->mapping = pmf->mapping;
|
|
newPMF->otherMappings = pmf->otherMappings;
|
|
pmf->otherMappings = newPMF;
|
|
}
|
|
pmf->mapping = existing;
|
|
} else {
|
|
existing->actual = mapping->actual;
|
|
existing->extended = mapping->extended;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void ParamMappingFunction_Remove(ParamMappingFunction *pmf, ParamMapping *mapping) {
|
|
ParamMappingFunction *prev;
|
|
ParamMappingFunction *tmp;
|
|
|
|
IRO_ASSERT(3170, pmf != NULL);
|
|
IRO_ASSERT(3171, mapping != NULL);
|
|
|
|
prev = NULL;
|
|
while (pmf && pmf->mapping) {
|
|
if (pmf->mapping->formal == mapping->formal) {
|
|
ParamMapping_Term(pmf->mapping);
|
|
ParamMapping_Delete(pmf->mapping);
|
|
if (!prev) {
|
|
if (pmf->otherMappings == NULL) {
|
|
pmf->mapping = NULL;
|
|
} else {
|
|
tmp = pmf->otherMappings;
|
|
pmf->mapping = pmf->otherMappings->mapping;
|
|
pmf->otherMappings = pmf->otherMappings->otherMappings;
|
|
tmp->mapping = NULL;
|
|
tmp->otherMappings = NULL;
|
|
ParamMappingFunction_Term(tmp);
|
|
ParamMappingFunction_Delete(tmp);
|
|
}
|
|
} else {
|
|
prev->otherMappings = pmf->otherMappings;
|
|
pmf->mapping = NULL;
|
|
pmf->otherMappings = NULL;
|
|
ParamMappingFunction_Term(pmf);
|
|
ParamMappingFunction_Delete(pmf);
|
|
}
|
|
return;
|
|
}
|
|
|
|
prev = pmf;
|
|
pmf = pmf->otherMappings;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void ParamMappingFunction_RemoveAll(ParamMappingFunction *pmf) {
|
|
IRO_ASSERT(3213, pmf != NULL);
|
|
|
|
while (pmf && pmf->mapping)
|
|
ParamMappingFunction_Remove(pmf, pmf->mapping);
|
|
}
|
|
|
|
CW_INLINE void ParamMappingFunction_AddFunctionAction(ParamMapping *mapping, void *refcon) {
|
|
IRO_ASSERT(3223, mapping != NULL);
|
|
IRO_ASSERT(3224, refcon != NULL);
|
|
|
|
Pmf_Add_sub_486610((ParamMappingFunction *) refcon, mapping);
|
|
}
|
|
|
|
CW_INLINE void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *dest, ParamMappingFunction *src) {
|
|
IRO_ASSERT(3231, dest != NULL);
|
|
IRO_ASSERT(3232, src != NULL);
|
|
|
|
pmf_sub_487C70(src, ParamMappingFunction_AddFunctionAction, dest);
|
|
}
|
|
|
|
CW_INLINE PointsToEntry *PointsToEntry_New(void) {
|
|
PointsToEntry *pte = IRO_malloc(sizeof(PointsToEntry));
|
|
|
|
IRO_ASSERT(3288, pte != NULL);
|
|
#ifdef IRO_DEBUG
|
|
pte->loc = NULL;
|
|
pte->locs = NULL;
|
|
#endif
|
|
return pte;
|
|
}
|
|
|
|
CW_INLINE void PointsToEntry_Delete(PointsToEntry *pte) {
|
|
IRO_ASSERT(3300, pte != NULL);
|
|
IRO_ASSERT(3301, pte->loc == NULL);
|
|
IRO_ASSERT(3302, pte->locs == NULL);
|
|
IRO_DEBUG_CLEAR(pte, sizeof(PointsToEntry));
|
|
IRO_free(pte);
|
|
}
|
|
|
|
CW_INLINE void PointsToEntry_Init(PointsToEntry *pte, LocationSet *loc, LocationSetSet *locs) {
|
|
IRO_ASSERT(3312, pte != NULL);
|
|
IRO_ASSERT(3313, loc != NULL);
|
|
IRO_ASSERT(3314, !LocationSet_IsUnknown(loc));
|
|
IRO_ASSERT(3315, locs != NULL);
|
|
|
|
pte->loc = LocationSet_New();
|
|
LocationSet_Copy(pte->loc, loc);
|
|
|
|
pte->locs = LocationSetSet_New();
|
|
LocationSetSet_Copy(pte->locs, locs);
|
|
}
|
|
|
|
CW_INLINE void PointsToEntry_Copy(PointsToEntry *dest, PointsToEntry *src) {
|
|
IRO_ASSERT(3325, src != NULL);
|
|
IRO_ASSERT(3326, dest != NULL);
|
|
|
|
PointsToEntry_Init(dest, src->loc, src->locs);
|
|
}
|
|
|
|
CW_INLINE void PointsToEntry_Term(PointsToEntry *pte) {
|
|
IRO_ASSERT(3333, pte != NULL);
|
|
|
|
LocationSet_Term(pte->loc);
|
|
LocationSet_Delete(pte->loc);
|
|
LocationSetSet_Term(pte->locs);
|
|
LocationSetSet_Delete(pte->locs);
|
|
|
|
#ifdef IRO_DEBUG
|
|
pte->loc = NULL;
|
|
pte->locs = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE Boolean PointsToEntries_Equal(PointsToEntry *pte1, PointsToEntry *pte2) {
|
|
IRO_ASSERT(3381, pte1 != NULL);
|
|
IRO_ASSERT(3382, pte2 != NULL);
|
|
|
|
if (pte1 == pte2)
|
|
return 1;
|
|
|
|
return LocationSets_Equal(pte1->loc, pte2->loc) && LocationSetSets_Equal(pte1->locs, pte2->locs);
|
|
}
|
|
|
|
CW_INLINE LocationSet *PointsToEntry_loc(PointsToEntry *pte) {
|
|
IRO_ASSERT(3407, pte != NULL);
|
|
|
|
return pte->loc;
|
|
}
|
|
|
|
CW_INLINE LocationSetSet *PointsToEntry_locs(PointsToEntry *pte) {
|
|
IRO_ASSERT(3414, pte != NULL);
|
|
|
|
return pte->locs;
|
|
}
|
|
|
|
CW_INLINE PointsToFunction *PointsToFunction_New(void) {
|
|
PointsToFunction *pointsToFunc = IRO_malloc(sizeof(PointsToFunction));
|
|
|
|
IRO_ASSERT(3430, pointsToFunc != NULL);
|
|
#ifdef IRO_DEBUG
|
|
pointsToFunc->pte = NULL;
|
|
pointsToFunc->otherPtes = NULL;
|
|
#endif
|
|
return pointsToFunc;
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_Delete(PointsToFunction *pointsToFunc) {
|
|
IRO_ASSERT(3442, pointsToFunc != NULL);
|
|
IRO_ASSERT(3443, pointsToFunc->pte == NULL);
|
|
IRO_ASSERT(3444, pointsToFunc->otherPtes == NULL);
|
|
IRO_DEBUG_CLEAR(pointsToFunc, sizeof(PointsToFunction));
|
|
IRO_free(pointsToFunc);
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_Init(PointsToFunction *pointsToFunc) {
|
|
IRO_ASSERT(3454, pointsToFunc != NULL);
|
|
|
|
pointsToFunc->pte = NULL;
|
|
pointsToFunc->otherPtes = NULL;
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_Copy(PointsToFunction *dest, PointsToFunction *src) {
|
|
IRO_ASSERT(3462, src != NULL);
|
|
IRO_ASSERT(3463, dest != NULL);
|
|
|
|
dest->pte = NULL;
|
|
dest->otherPtes = NULL;
|
|
PointsToFunction_AddAllIGuess_sub_487D80(dest, src);
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_Term(PointsToFunction *pointsToFunc) {
|
|
IRO_ASSERT(3472, pointsToFunc != NULL);
|
|
|
|
PointsToFunction_RemoveAll(pointsToFunc);
|
|
|
|
#ifdef IRO_DEBUG
|
|
pointsToFunc->pte = NULL;
|
|
pointsToFunc->otherPtes = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_ForEach(PointsToFunction *pointsToFunc, void (*action)(PointsToEntry *, void *), void *refcon) {
|
|
IRO_ASSERT(3515, pointsToFunc != NULL);
|
|
IRO_ASSERT(3516, action != NULL);
|
|
IRO_ASSERT(3517, refcon == NULL || refcon != NULL);
|
|
|
|
while (pointsToFunc && pointsToFunc->pte) {
|
|
action(pointsToFunc->pte, refcon);
|
|
pointsToFunc = pointsToFunc->otherPtes;
|
|
}
|
|
}
|
|
|
|
CW_INLINE PointsToEntry *PointsToFunction_FindByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
|
|
IRO_ASSERT(3527, pointsToFunc != NULL);
|
|
IRO_ASSERT(3528, ls != NULL);
|
|
|
|
while (pointsToFunc && pointsToFunc->pte) {
|
|
if (LocationSets_Equal(pointsToFunc->pte->loc, ls))
|
|
return pointsToFunc->pte;
|
|
pointsToFunc = pointsToFunc->otherPtes;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE PointsToEntry *PointsToFunction_FindFirst(PointsToFunction *pointsToFunc) {
|
|
IRO_ASSERT(3539, pointsToFunc != NULL);
|
|
|
|
return pointsToFunc->pte;
|
|
}
|
|
|
|
CW_INLINE PointsToEntry *PointsToFunction_FindByLookupCompatibleLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
|
|
IRO_ASSERT(3546, pointsToFunc != NULL);
|
|
IRO_ASSERT(3547, ls != NULL);
|
|
|
|
while (pointsToFunc && pointsToFunc->pte) {
|
|
if (ls->u.known.stride) {
|
|
if (LocationSets_Equal(pointsToFunc->pte->loc, ls))
|
|
return pointsToFunc->pte;
|
|
} else if (LocationSets_LookupCompatible(pointsToFunc->pte->loc, ls)) {
|
|
return pointsToFunc->pte;
|
|
}
|
|
pointsToFunc = pointsToFunc->otherPtes;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE PointsToEntry *PointsToFunction_FindContainingLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls, Type *rtype) {
|
|
IRO_ASSERT(3565, pointsToFunc != NULL);
|
|
IRO_ASSERT(3566, ls != NULL);
|
|
IRO_ASSERT(3567, rtype != NULL);
|
|
|
|
while (pointsToFunc && pointsToFunc->pte) {
|
|
if (pointsToFunc->pte->locs->loc && !LocationSet_IsUnknown(pointsToFunc->pte->locs->loc)) {
|
|
if (!pointsToFunc->pte->locs->otherLocs && LocationSet_Contains(pointsToFunc->pte->loc, pointsToFunc->pte->locs->loc->rtype, ls, rtype))
|
|
return pointsToFunc->pte;
|
|
}
|
|
pointsToFunc = pointsToFunc->otherPtes;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_RemoveOverlappingLocations(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
|
|
Type *rtype1;
|
|
Type *rtype2;
|
|
LocationSet *ls;
|
|
PointsToFunction *prev;
|
|
PointsToFunction *next;
|
|
PointsToFunction *tmp;
|
|
|
|
IRO_ASSERT(3601, pointsToFunc != NULL);
|
|
IRO_ASSERT(3602, pte != NULL);
|
|
IRO_ASSERT(3603, pte->locs != NULL);
|
|
|
|
if (pte->locs->loc && pte->locs->loc != stUnknownLs)
|
|
rtype1 = pte->locs->loc->rtype;
|
|
else
|
|
rtype1 = NULL;
|
|
ls = pte->loc;
|
|
IRO_ASSERT(3614, ls != NULL);
|
|
|
|
prev = NULL;
|
|
while (pointsToFunc && pointsToFunc->pte) {
|
|
next = pointsToFunc->otherPtes;
|
|
if (pointsToFunc->pte->locs->loc && pointsToFunc->pte->locs->loc != stUnknownLs)
|
|
rtype2 = pointsToFunc->pte->locs->loc->rtype;
|
|
else
|
|
rtype2 = NULL;
|
|
|
|
if (LocationSets_Overlap(ls, rtype1, pointsToFunc->pte->loc, rtype2)) {
|
|
PointsToEntry_Term(pointsToFunc->pte);
|
|
PointsToEntry_Delete(pointsToFunc->pte);
|
|
if (!prev) {
|
|
if (pointsToFunc->otherPtes == NULL) {
|
|
pointsToFunc->pte = NULL;
|
|
prev = pointsToFunc;
|
|
} else {
|
|
tmp = pointsToFunc->otherPtes;
|
|
pointsToFunc->pte = pointsToFunc->otherPtes->pte;
|
|
pointsToFunc->otherPtes = pointsToFunc->otherPtes->otherPtes;
|
|
tmp->pte = NULL;
|
|
tmp->otherPtes = NULL;
|
|
PointsToFunction_Term(tmp);
|
|
PointsToFunction_Delete(tmp);
|
|
prev = NULL;
|
|
next = pointsToFunc;
|
|
}
|
|
} else {
|
|
prev->otherPtes = pointsToFunc->otherPtes;
|
|
pointsToFunc->pte = NULL;
|
|
pointsToFunc->otherPtes = NULL;
|
|
PointsToFunction_Term(pointsToFunc);
|
|
PointsToFunction_Delete(pointsToFunc);
|
|
prev = pointsToFunc;
|
|
}
|
|
}
|
|
|
|
pointsToFunc = next;
|
|
}
|
|
}
|
|
|
|
CW_INLINE Boolean ShouldAddNewPointsToEntryToFunction(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
|
|
Boolean flag;
|
|
Boolean isKnown;
|
|
SInt32 stride;
|
|
PointsToFunction *next;
|
|
LocationSet *loc;
|
|
LocationSet *loc2;
|
|
Type *rtype1;
|
|
Type *rtype2;
|
|
LocationSetSet *locs2;
|
|
LocationSet *tmp;
|
|
LocationSet *unknown;
|
|
Boolean flag2;
|
|
Boolean flag3;
|
|
|
|
IRO_ASSERT(3675, pointsToFunc != NULL);
|
|
IRO_ASSERT(3676, pte != NULL);
|
|
IRO_ASSERT(3677, pte->locs != NULL);
|
|
IRO_ASSERT(3678, PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc) == NULL);
|
|
IRO_ASSERT(3679, (unknown = LocationSetSet_FindFirst(pte->locs)) != NULL);
|
|
IRO_ASSERT(3680, LocationSet_IsUnknown(unknown));
|
|
IRO_ASSERT(3681, LocationSet_bitfieldOf(unknown) == NULL);
|
|
IRO_ASSERT(3682, LocationSet_restriction(unknown) == NULL);
|
|
|
|
if (pte->locs->loc && pte->locs->loc != stUnknownLs)
|
|
rtype1 = pte->locs->loc->rtype;
|
|
else
|
|
rtype1 = NULL;
|
|
|
|
loc = pte->loc;
|
|
IRO_ASSERT(3693, loc != NULL);
|
|
|
|
isKnown = !LocationSet_IsUnknown(loc);
|
|
if (isKnown)
|
|
stride = LocationSet_stride(loc);
|
|
|
|
flag = 0;
|
|
while (pointsToFunc && pointsToFunc->pte) {
|
|
next = pointsToFunc->otherPtes;
|
|
|
|
locs2 = pointsToFunc->pte->locs;
|
|
|
|
if (locs2->loc && locs2->loc != stUnknownLs)
|
|
rtype2 = locs2->loc->rtype;
|
|
else
|
|
rtype2 = NULL;
|
|
|
|
loc2 = pointsToFunc->pte->loc;
|
|
|
|
flag2 = !(tmp = LocationSetSet_FindFirst(locs2)) ||
|
|
!LocationSet_IsUnknown(tmp) ||
|
|
LocationSet_bitfieldOf(tmp) ||
|
|
LocationSet_restriction(tmp);
|
|
|
|
flag3 = LocationSets_Overlap(loc, rtype1, loc2, rtype2);
|
|
|
|
if (!flag && flag3)
|
|
flag = 1;
|
|
|
|
if (flag3 && (flag2 || (isKnown && stride && LocationSet_stride(loc2) == 0)))
|
|
return 1;
|
|
|
|
pointsToFunc = next;
|
|
}
|
|
|
|
return !flag;
|
|
}
|
|
|
|
CW_INLINE Boolean PointsToFunction_SimpleAdd(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
|
|
PointsToEntry *newPTE;
|
|
|
|
IRO_ASSERT(3741, pointsToFunc != NULL);
|
|
IRO_ASSERT(3742, pte != NULL);
|
|
|
|
newPTE = PointsToEntry_New();
|
|
PointsToEntry_Copy(newPTE, pte);
|
|
if (pointsToFunc->pte) {
|
|
PointsToFunction *newPointsToFunc = PointsToFunction_New();
|
|
PointsToFunction_Init(newPointsToFunc);
|
|
newPointsToFunc->pte = pointsToFunc->pte;
|
|
newPointsToFunc->otherPtes = pointsToFunc->otherPtes;
|
|
pointsToFunc->otherPtes = newPointsToFunc;
|
|
}
|
|
pointsToFunc->pte = newPTE;
|
|
return 1;
|
|
}
|
|
|
|
CW_INLINE Boolean PointsToFunction_Add(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
|
|
IRO_ASSERT(3766, pointsToFunc != NULL);
|
|
IRO_ASSERT(3767, pte != NULL);
|
|
|
|
if (!PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc)) {
|
|
LocationSet *ls;
|
|
if (!(ls = LocationSetSet_FindFirst(pte->locs)) || !LocationSet_IsUnknown(ls) || LocationSet_bitfieldOf(ls) ||
|
|
LocationSet_restriction(ls) || ShouldAddNewPointsToEntryToFunction(pointsToFunc, pte)) {
|
|
PointsToFunction_RemoveOverlappingLocations(pointsToFunc, pte);
|
|
if (!LocationSet_IsUnknown(pte->loc) || pte->loc->rtype)
|
|
PointsToFunction_SimpleAdd(pointsToFunc, pte);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
CW_INLINE Boolean PointsToFunction_AddWithoutChecking(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
|
|
LocationSet *ls;
|
|
|
|
IRO_ASSERT(3793, pointsToFunc != NULL);
|
|
IRO_ASSERT(3794, pte != NULL);
|
|
|
|
if (!(ls = LocationSetSet_FindFirst(pte->locs)) || !LocationSet_IsUnknown(ls) || LocationSet_bitfieldOf(ls) ||
|
|
LocationSet_restriction(ls) || ShouldAddNewPointsToEntryToFunction(pointsToFunc, pte)) {
|
|
PointsToFunction_RemoveOverlappingLocations(pointsToFunc, pte);
|
|
if (!LocationSet_IsUnknown(pte->loc) || pte->loc->rtype)
|
|
PointsToFunction_SimpleAdd(pointsToFunc, pte);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_RemoveByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
|
|
PointsToFunction *prev;
|
|
PointsToFunction *tmp;
|
|
|
|
IRO_ASSERT(3170, pointsToFunc != NULL);
|
|
IRO_ASSERT(3171, ls != NULL);
|
|
IRO_ASSERT(3172, !LocationSet_IsUnknown(ls));
|
|
|
|
prev = NULL;
|
|
while (pointsToFunc && pointsToFunc->pte) {
|
|
if (LocationSets_Equal(pointsToFunc->pte->loc, ls)) {
|
|
PointsToEntry_Term(pointsToFunc->pte);
|
|
PointsToEntry_Delete(pointsToFunc->pte);
|
|
if (!prev) {
|
|
if (pointsToFunc->otherPtes == NULL) {
|
|
pointsToFunc->pte = NULL;
|
|
} else {
|
|
tmp = pointsToFunc->otherPtes;
|
|
pointsToFunc->pte = pointsToFunc->otherPtes->pte;
|
|
pointsToFunc->otherPtes = pointsToFunc->otherPtes->otherPtes;
|
|
tmp->pte = NULL;
|
|
tmp->otherPtes = NULL;
|
|
PointsToFunction_Term(tmp);
|
|
PointsToFunction_Delete(tmp);
|
|
}
|
|
} else {
|
|
prev->otherPtes = pointsToFunc->otherPtes;
|
|
pointsToFunc->pte = NULL;
|
|
pointsToFunc->otherPtes = NULL;
|
|
PointsToFunction_Term(pointsToFunc);
|
|
PointsToFunction_Delete(pointsToFunc);
|
|
}
|
|
return;
|
|
}
|
|
|
|
prev = pointsToFunc;
|
|
pointsToFunc = pointsToFunc->otherPtes;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_RemoveAll(PointsToFunction *pointsToFunc) {
|
|
IRO_ASSERT(3862, pointsToFunc != NULL);
|
|
|
|
while (pointsToFunc && pointsToFunc->pte)
|
|
PointsToFunction_RemoveByLocationSet(pointsToFunc, pointsToFunc->pte->loc);
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_AddFunctionAction(PointsToEntry *pte, void *refcon) {
|
|
IRO_ASSERT(3872, pte != NULL);
|
|
IRO_ASSERT(3873, refcon != NULL);
|
|
|
|
PointsToFunction_Add((PointsToFunction *) refcon, pte);
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_SimpleAddFunctionAction(PointsToEntry *pte, void *refcon) {
|
|
IRO_ASSERT(3880, pte != NULL);
|
|
IRO_ASSERT(3881, refcon != NULL);
|
|
|
|
PointsToFunction_SimpleAdd((PointsToFunction *) refcon, pte);
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_AddAllIGuess_sub_487D80(PointsToFunction *dest, PointsToFunction *src) {
|
|
IRO_ASSERT(3888, dest != NULL);
|
|
IRO_ASSERT(3889, src != NULL);
|
|
|
|
if (dest->pte)
|
|
PointsToFunction_ForEach(src, PointsToFunction_AddFunctionAction, dest);
|
|
else
|
|
PointsToFunction_ForEach(src, PointsToFunction_SimpleAddFunctionAction, dest);
|
|
}
|
|
|
|
CW_INLINE void PointsToFunction_SortByExtendedParamNum(PointsToFunction *pointsToFunc) {
|
|
UInt32 value1;
|
|
UInt32 value2;
|
|
PointsToFunction *scan;
|
|
|
|
while (pointsToFunc && pointsToFunc->pte) {
|
|
value1 = 0;
|
|
if (pointsToFunc->pte->loc && pointsToFunc->pte->loc->block) {
|
|
PAMemoryBlock *block = pointsToFunc->pte->loc->block;
|
|
if (block->kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM && block->u.ep) {
|
|
value1 = 2 * (block->u.ep->x4) + 1;
|
|
} else if (block->kind == PAMEMORYBLOCKKIND_LOCALVAR && block->u.localvar) {
|
|
if (block->u.localvar->x0 && block->u.localvar->x0->extParam)
|
|
value1 = 2 * block->u.localvar->x0->extParam->x4;
|
|
}
|
|
}
|
|
|
|
for (scan = pointsToFunc->otherPtes; scan && scan->pte; scan = scan->otherPtes) {
|
|
value2 = 0;
|
|
if (scan->pte->loc && scan->pte->loc->block) {
|
|
PAMemoryBlock *block = scan->pte->loc->block;
|
|
if (block->kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM && block->u.ep) {
|
|
value2 = 2 * (block->u.ep->x4) + 1;
|
|
} else if (block->kind == PAMEMORYBLOCKKIND_LOCALVAR && block->u.localvar) {
|
|
if (block->u.localvar->x0 && block->u.localvar->x0->extParam)
|
|
value2 = 2 * block->u.localvar->x0->extParam->x4;
|
|
}
|
|
}
|
|
|
|
if (value2 < value1) {
|
|
LocationSet *saveloc;
|
|
LocationSetSet *savelocs;
|
|
saveloc = pointsToFunc->pte->loc;
|
|
savelocs = pointsToFunc->pte->locs;
|
|
pointsToFunc->pte->loc = scan->pte->loc;
|
|
pointsToFunc->pte->locs = scan->pte->locs;
|
|
scan->pte->loc = saveloc;
|
|
scan->pte->locs = savelocs;
|
|
}
|
|
}
|
|
|
|
pointsToFunc = pointsToFunc->otherPtes;
|
|
}
|
|
}
|
|
|
|
CW_INLINE Boolean PointsToFunctions_Equal(PointsToFunction *pointsToFunc1, PointsToFunction *pointsToFunc2) {
|
|
PointsToFunction *scan;
|
|
PointsToEntry *pte;
|
|
|
|
IRO_ASSERT(3968, pointsToFunc1 != NULL);
|
|
IRO_ASSERT(3969, pointsToFunc2 != NULL);
|
|
|
|
if (pointsToFunc1 == pointsToFunc2)
|
|
return 1;
|
|
|
|
for (scan = pointsToFunc1; scan && scan->pte; scan = scan->otherPtes) {
|
|
pte = PointsToFunction_FindByLocationSet(pointsToFunc2, scan->pte->loc);
|
|
if (!pte || !PointsToEntries_Equal(pte, scan->pte))
|
|
return 0;
|
|
}
|
|
|
|
for (scan = pointsToFunc2; scan && scan->pte; scan = scan->otherPtes) {
|
|
pte = PointsToFunction_FindByLocationSet(pointsToFunc1, scan->pte->loc);
|
|
if (!pte || !PointsToEntries_Equal(pte, scan->pte))
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
CW_INLINE Boolean PointsToFunctions_Match(PointsToFunction *pointsToFunc1, PointsToFunction *pointsToFunc2) {
|
|
return 1;
|
|
}
|
|
|
|
CW_INLINE PartialTransferFunction *PartialTransferFunction_New(void) {
|
|
PartialTransferFunction *ptf = IRO_malloc(sizeof(PartialTransferFunction));
|
|
|
|
IRO_ASSERT(4110, ptf != NULL);
|
|
#ifdef IRO_DEBUG
|
|
ptf->initialPointsToFn = NULL;
|
|
ptf->finalPointsToFn = NULL;
|
|
ptf->funcModifies = NULL;
|
|
ptf->context.nd = NULL;
|
|
ptf->context.ptf = NULL;
|
|
ptf->returnLocation = NULL;
|
|
#endif
|
|
return ptf;
|
|
}
|
|
|
|
CW_INLINE void PartialTransferFunction_Delete(PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4126, ptf != NULL);
|
|
IRO_ASSERT(4127, ptf->initialPointsToFn == NULL);
|
|
IRO_ASSERT(4128, ptf->finalPointsToFn == NULL);
|
|
IRO_ASSERT(4129, ptf->funcModifies == NULL);
|
|
IRO_ASSERT(4130, ptf->context.nd == NULL);
|
|
IRO_ASSERT(4131, ptf->context.ptf == NULL);
|
|
IRO_ASSERT(4132, ptf->returnLocation == NULL);
|
|
IRO_DEBUG_CLEAR(ptf, sizeof(PartialTransferFunction));
|
|
IRO_free(ptf);
|
|
}
|
|
|
|
CW_INLINE void PartialTransferFunction_Init(PartialTransferFunction *ptf, IROLinear *contextNd, PartialTransferFunction *contextPTF) {
|
|
IRO_ASSERT(4142, ptf != NULL);
|
|
IRO_ASSERT(4143, contextNd != NULL);
|
|
IRO_ASSERT(4144, contextPTF != NULL);
|
|
|
|
ptf->initialPointsToFn = PointsToFunction_New();
|
|
PointsToFunction_Init(ptf->initialPointsToFn);
|
|
ptf->finalPointsToFn = PointsToFunction_New();
|
|
PointsToFunction_Init(ptf->finalPointsToFn);
|
|
|
|
ptf->funcModifies = LocationSetSet_New();
|
|
LocationSetSet_Init(ptf->funcModifies);
|
|
LocationSetSet_AddUnknown(ptf->funcModifies, NULL, NULL, NULL);
|
|
|
|
ptf->returnLocation = NULL;
|
|
ptf->x10 = 0;
|
|
|
|
ptf->context.nd = contextNd;
|
|
ptf->context.ptf = contextPTF;
|
|
}
|
|
|
|
CW_INLINE void PartialTransferFunction_Copy(PartialTransferFunction *dest, PartialTransferFunction *src) {
|
|
IRO_ASSERT(4164, src != NULL);
|
|
IRO_ASSERT(4165, dest != NULL);
|
|
|
|
dest->initialPointsToFn = PointsToFunction_New();
|
|
PointsToFunction_Copy(dest->initialPointsToFn, src->initialPointsToFn);
|
|
dest->finalPointsToFn = PointsToFunction_New();
|
|
PointsToFunction_Copy(dest->finalPointsToFn, src->finalPointsToFn);
|
|
|
|
dest->funcModifies = LocationSetSet_New();
|
|
LocationSetSet_Copy(dest->funcModifies, src->funcModifies);
|
|
|
|
if (src->returnLocation) {
|
|
dest->returnLocation = LocationSet_New();
|
|
LocationSet_Copy(dest->returnLocation, src->returnLocation);
|
|
} else {
|
|
dest->returnLocation = NULL;
|
|
}
|
|
|
|
dest->x10 = src->x10;
|
|
dest->context = src->context;
|
|
}
|
|
|
|
CW_INLINE void PartialTransferFunction_Term(PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4190, ptf != NULL);
|
|
|
|
PointsToFunction_Term(ptf->initialPointsToFn);
|
|
PointsToFunction_Delete(ptf->initialPointsToFn);
|
|
PointsToFunction_Term(ptf->finalPointsToFn);
|
|
PointsToFunction_Delete(ptf->finalPointsToFn);
|
|
LocationSetSet_Term(ptf->funcModifies);
|
|
LocationSetSet_Delete(ptf->funcModifies);
|
|
|
|
if (ptf->returnLocation) {
|
|
PAMemoryBlock_Term(ptf->returnLocation->block);
|
|
PAMemoryBlock_Delete(ptf->returnLocation->block);
|
|
LocationSet_Term(ptf->returnLocation);
|
|
LocationSet_Delete(ptf->returnLocation);
|
|
ptf->returnLocation = NULL;
|
|
}
|
|
|
|
#ifdef IRO_DEBUG
|
|
ptf->initialPointsToFn = NULL;
|
|
ptf->finalPointsToFn = NULL;
|
|
ptf->funcModifies = NULL;
|
|
ptf->context.nd = NULL;
|
|
ptf->context.ptf = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE PointsToFunction *PartialTransferFunction_initialPointsToFn(PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4221, ptf != NULL);
|
|
|
|
return ptf->initialPointsToFn;
|
|
}
|
|
|
|
CW_INLINE PointsToFunction *PartialTransferFunction_finalPointsToFn(PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4227, ptf != NULL);
|
|
|
|
return ptf->finalPointsToFn;
|
|
}
|
|
|
|
CW_INLINE LocationSetSet *PTF_sub_48D750(PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4233, ptf != NULL);
|
|
|
|
return ptf->funcModifies;
|
|
}
|
|
|
|
CW_INLINE LocationSet *PartialTransferFunction_returnLocation(PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4249, ptf != NULL);
|
|
|
|
if (!ptf->returnLocation) {
|
|
PAMemoryBlock *block;
|
|
LocationSet *ls;
|
|
|
|
block = PAMemoryBlock_New();
|
|
PAMemoryBlock_Init(block, PAMEMORYBLOCKKIND_LOCALVAR, NULL);
|
|
ls = LocationSet_New();
|
|
LocationSet_InitKnown(ls, block, cint64_zero, 0, TYPE(&void_ptr));
|
|
ptf->returnLocation = ls;
|
|
}
|
|
|
|
return ptf->returnLocation;
|
|
}
|
|
|
|
CW_INLINE IROLinear *PTF_sub_48B980(PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4265, ptf != NULL);
|
|
|
|
return ptf->context.nd;
|
|
}
|
|
|
|
CW_INLINE PartialTransferFunction *PTF_sub_48B970(PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4271, ptf != NULL);
|
|
|
|
return ptf->context.ptf;
|
|
}
|
|
|
|
CW_INLINE void PartialTransferFunction_sub_48A610(PartialTransferFunction *ptf, Boolean value) {
|
|
IRO_ASSERT(4298, ptf != NULL);
|
|
|
|
ptf->x10 = (value != 0) ? 1 : 0;
|
|
}
|
|
|
|
CW_INLINE PTFList *PTFList_New(void) {
|
|
PTFList *ptfList = IRO_malloc(sizeof(PTFList));
|
|
|
|
IRO_ASSERT(4393, ptfList != NULL);
|
|
#ifdef IRO_DEBUG
|
|
ptfList->ptf = NULL;
|
|
ptfList->otherPTFs = NULL;
|
|
#endif
|
|
return ptfList;
|
|
}
|
|
|
|
CW_INLINE void PTFList_Delete(PTFList *ptfList) {
|
|
IRO_ASSERT(4405, ptfList != NULL);
|
|
IRO_ASSERT(4406, ptfList->ptf == NULL);
|
|
IRO_ASSERT(4407, ptfList->otherPTFs == NULL);
|
|
IRO_DEBUG_CLEAR(ptfList, sizeof(PTFList));
|
|
IRO_free(ptfList);
|
|
}
|
|
|
|
CW_INLINE void PTFList_Init(PTFList *ptfList) {
|
|
IRO_ASSERT(4417, ptfList != NULL);
|
|
|
|
ptfList->ptf = NULL;
|
|
ptfList->otherPTFs = NULL;
|
|
}
|
|
|
|
CW_INLINE void PTFList_Term(PTFList *ptfList) {
|
|
IRO_ASSERT(4435, ptfList != NULL);
|
|
|
|
PTFList_RemoveAll(ptfList);
|
|
|
|
#ifdef IRO_DEBUG
|
|
ptfList->ptf = NULL;
|
|
ptfList->otherPTFs = NULL;
|
|
#endif
|
|
}
|
|
|
|
CW_INLINE void PTFList_ForEach(PTFList *ptfList, void (*action)(PartialTransferFunction *, void *), void *refcon) {
|
|
IRO_ASSERT(4478, ptfList != NULL);
|
|
IRO_ASSERT(4479, action != NULL);
|
|
IRO_ASSERT(4480, refcon == NULL || refcon != NULL);
|
|
|
|
while (ptfList && ptfList->ptf) {
|
|
action(ptfList->ptf, refcon);
|
|
ptfList = ptfList->otherPTFs;
|
|
}
|
|
}
|
|
|
|
CW_INLINE PartialTransferFunction *PTFList_sub_48A0F0(PTFList *ptfList, PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4490, ptfList != NULL);
|
|
IRO_ASSERT(4491, ptf != NULL);
|
|
|
|
while (ptfList && ptfList->ptf) {
|
|
if (ptfList->ptf == ptf)
|
|
return ptfList->ptf;
|
|
|
|
ptfList = ptfList->otherPTFs;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
CW_INLINE PartialTransferFunction *PTFList_FindFirst(PTFList *ptfList) {
|
|
IRO_ASSERT(4502, ptfList != NULL);
|
|
|
|
return ptfList->ptf;
|
|
}
|
|
|
|
CW_INLINE void PTFList_sub_48A080(PTFList *ptfList, PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4511, ptfList != NULL);
|
|
IRO_ASSERT(4512, ptf != NULL);
|
|
|
|
if (ptfList->ptf) {
|
|
PTFList *newList = PTFList_New();
|
|
PTFList_Init(newList);
|
|
newList->ptf = ptfList->ptf;
|
|
newList->otherPTFs = ptfList->otherPTFs;
|
|
ptfList->otherPTFs = newList;
|
|
}
|
|
|
|
ptfList->ptf = ptf;
|
|
}
|
|
|
|
CW_INLINE void PTFList_sub_48A050(PTFList *ptfList, PartialTransferFunction *ptf) {
|
|
IRO_ASSERT(4529, ptfList != NULL);
|
|
IRO_ASSERT(4530, ptf != NULL);
|
|
|
|
if (!PTFList_sub_48A0F0(ptfList, ptf))
|
|
PTFList_sub_48A080(ptfList, ptf);
|
|
}
|
|
|
|
CW_INLINE void PTFList_Remove(PTFList *ptfList, PartialTransferFunction *ptf) {
|
|
PTFList *prev;
|
|
PTFList *tmp;
|
|
|
|
IRO_ASSERT(4542, ptfList != NULL);
|
|
IRO_ASSERT(4543, ptf != NULL);
|
|
|
|
prev = NULL;
|
|
while (ptfList && ptfList->ptf) {
|
|
if (ptfList->ptf == ptf) {
|
|
if (!prev) {
|
|
if (ptfList->otherPTFs == NULL) {
|
|
ptfList->ptf = NULL;
|
|
} else {
|
|
tmp = ptfList->otherPTFs;
|
|
ptfList->ptf = ptfList->otherPTFs->ptf;
|
|
ptfList->otherPTFs = ptfList->otherPTFs->otherPTFs;
|
|
tmp->ptf = NULL;
|
|
tmp->otherPTFs = NULL;
|
|
PTFList_Term(tmp);
|
|
PTFList_Delete(tmp);
|
|
}
|
|
} else {
|
|
prev->otherPTFs = ptfList->otherPTFs;
|
|
ptfList->ptf = NULL;
|
|
ptfList->otherPTFs = NULL;
|
|
PTFList_Term(ptfList);
|
|
PTFList_Delete(ptfList);
|
|
}
|
|
return;
|
|
}
|
|
|
|
prev = ptfList;
|
|
ptfList = ptfList->otherPTFs;
|
|
}
|
|
}
|
|
|
|
CW_INLINE void PTFList_RemoveAll(PTFList *ptfList) {
|
|
IRO_ASSERT(4582, ptfList != NULL);
|
|
|
|
while (ptfList && ptfList->ptf)
|
|
PTFList_Remove(ptfList, ptfList->ptf);
|
|
}
|