MWCC/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c

2734 lines
79 KiB
C
Raw Normal View History

#include "compiler/IroPointerAnalysis.h"
#include "compiler/IroMalloc.h"
#include "compiler/CError.h"
#include "compiler/CInt64.h"
// TODO: this should really be elsewhere (but where?)
2023-01-11 23:26:04 +00:00
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
2023-01-10 11:05:21 +00:00
#define IRO_ASSERT(line, expr) \
do { \
if (!(expr)) { \
2023-01-10 11:05:21 +00:00
__assertion_failed(#expr, __FILE__, line); \
} \
} while (0);
#define IRO_DEBUG_CLEAR(obj, type) \
memset((obj), 0xFF, sizeof(type))
#else
2023-01-10 11:05:21 +00:00
#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
2023-01-11 23:26:04 +00:00
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));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(103, stackElement != NULL);
#ifdef IRO_DEBUG
stackElement->proc = NULL;
stackElement->ptf = NULL;
stackElement->map = NULL;
stackElement->funcCall = NULL;
#endif
return stackElement;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void StackElement_Delete(StackElement *stackElement) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void StackElement_Init(StackElement *stackElement, Object *proc, PartialTransferFunction *ptf, ParamMappingFunction *map, IROLinear *funcCall) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void StackElement_Copy(StackElement *dest, StackElement *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(145, dest != NULL);
IRO_ASSERT(146, src != NULL);
StackElement_Init(dest, src->proc, src->ptf, src->map, src->funcCall);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void StackElement_Term(StackElement *stackElement) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(156, stackElement != NULL);
#ifdef IRO_DEBUG
stackElement->proc = NULL;
stackElement->ptf = NULL;
stackElement->map = NULL;
stackElement->funcCall = NULL;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE void *StackElement_sub_48A780(StackElement *stackElement) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(213, stackElement != NULL);
return stackElement->proc;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean StackRelated_sub_48A760(void *key1, void *key2) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(220, key1 != NULL);
IRO_ASSERT(221, key2 != NULL);
return key1 == key2;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Object *StackElement_proc(StackElement *stackElement) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(228, stackElement != NULL);
return stackElement->proc;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PartialTransferFunction *StackElement_ptf(StackElement *stackElement) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(235, stackElement != NULL);
return stackElement->ptf;
}
2023-01-11 23:26:04 +00:00
CW_INLINE ParamMappingFunction *StackElement_map(StackElement *stackElement) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(242, stackElement != NULL);
return stackElement->map;
}
2023-01-11 23:26:04 +00:00
CW_INLINE IROLinear *StackElement_funcCall(StackElement *stackElement) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(249, stackElement != NULL);
return stackElement->funcCall;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Stack *Stack_New(void) {
Stack *stack = IRO_malloc(sizeof(Stack));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(265, stack != NULL);
#ifdef IRO_DEBUG
stack->top = NULL;
stack->next = NULL;
#endif
return stack;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void Stack_Delete(Stack *stack) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void Stack_Init(Stack *stack) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(289, stack != NULL);
stack->top = NULL;
stack->next = NULL;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void Stack_Term(Stack **stackPtr) {
StackElement *stackElement;
2023-01-10 11:05:21 +00:00
IRO_ASSERT(299, stackPtr != NULL);
IRO_ASSERT(300, *stackPtr != NULL);
while ((*stackPtr)->top) {
stackElement = Stack_sub_48A5B0(stackPtr);
StackElement_Term(stackElement);
StackElement_Delete(stackElement);
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void Stack_sub_48A660(Stack **stackPtr, StackElement *stackElement) {
StackElement *newElement;
Stack *newStack;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE StackElement *Stack_Top(Stack **stackPtr) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(331, stackPtr != NULL);
IRO_ASSERT(332, *stackPtr != NULL);
return (*stackPtr)->top;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Stack *Stack_Next(Stack **stackPtr) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(343, stackPtr != NULL);
IRO_ASSERT(344, *stackPtr != NULL);
return (*stackPtr)->next;
}
2023-01-11 23:26:04 +00:00
CW_INLINE StackElement *Stack_sub_48A5B0(Stack **stackPtr) {
StackElement *stackElement;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE StackElement *Stack_sub_48A710(Stack **stackPtr, void *key) {
Stack *stack;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE ObjectSet *ObjectSet_New(void) {
ObjectSet *procList;
procList = IRO_malloc(sizeof(ObjectSet));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(439, procList != NULL);
#ifdef IRO_DEBUG
procList->proc = NULL;
procList->otherProcs = NULL;
#endif
return procList;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_Delete(ObjectSet *procList) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_Init(ObjectSet *procList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(463, procList != NULL);
procList->proc = NULL;
procList->otherProcs = NULL;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_Term(ObjectSet *procList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(481, procList != NULL);
ObjectSet_RemoveAll(procList);
#ifdef IRO_DEBUG
procList->proc = NULL;
procList->otherProcs = NULL;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_ForEach(ObjectSet *procList, void (*action)(Object *, void *), void *refcon) {
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE Object *ObjectSet_sub_485020(ObjectSet *procList, Object *proc) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Object *ObjectSet_FindFirst(ObjectSet *procList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(552, procList != NULL);
return procList->proc;
}
2023-01-11 23:26:04 +00:00
CW_INLINE int ObjectSet_Count(ObjectSet *procList) {
int count;
2023-01-10 11:05:21 +00:00
IRO_ASSERT(561, procList != NULL);
count = 0;
while (procList && procList->proc) {
count++;
procList = procList->otherProcs;
}
return count;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_sub_486800(ObjectSet *procList, Object *proc) {
ObjectSet *newProcList;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_sub_4867D0(ObjectSet *procList, Object *proc) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(592, procList != NULL);
IRO_ASSERT(593, proc != NULL);
if (!ObjectSet_sub_485020(procList, proc))
ObjectSet_sub_486800(procList, proc);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_Remove(ObjectSet *procList, Object *proc) {
ObjectSet *prev;
ObjectSet *tmp;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_RemoveAll(ObjectSet *procList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(645, procList != NULL);
while (procList && procList->proc)
ObjectSet_Remove(procList, procList->proc);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_AddSetAction(Object *proc, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(655, proc != NULL);
IRO_ASSERT(656, refcon != NULL);
ObjectSet_sub_4867D0(refcon, proc);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_SimpleAddSetAction(Object *proc, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(663, proc != NULL);
IRO_ASSERT(664, refcon != NULL);
ObjectSet_sub_486800(refcon, proc);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_sub_48C590(ObjectSet *dest, ObjectSet *src) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_RemoveSetAction(Object *proc, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(682, proc != NULL);
IRO_ASSERT(683, refcon != NULL);
ObjectSet_Remove(refcon, proc);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ObjectSet_removeiter_sub_48C890(ObjectSet *dest, ObjectSet *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(690, dest != NULL);
IRO_ASSERT(691, src != NULL);
ObjectSet_ForEach(src, ObjectSet_RemoveSetAction, dest);
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean ObjectSet_sub_484FA0(ObjectSet *os1, ObjectSet *os2) {
ObjectSet *scan;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE ExtendedParam *ExtendedParam_New(void) {
ExtendedParam *ep = IRO_malloc(sizeof(ExtendedParam));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(755, ep != NULL);
#ifdef IRO_DEBUG
ep->objectSet = NULL;
#endif
return ep;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtendedParam_Delete(ExtendedParam *ep) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(762, ep != NULL);
IRO_ASSERT(763, ep->objectSet == NULL);
IRO_DEBUG_CLEAR(ep, sizeof(ExtendedParam));
IRO_free(ep);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtendedParam_Init(ExtendedParam *ep, Object *obj) {
2023-01-10 11:05:21 +00:00
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++;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtendedParam_TermAction(Object *obj, void *refcon) {
obj->extParam = NULL;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtendedParam_Term(ExtendedParam *ep) {
2023-01-10 11:05:21 +00:00
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
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean ExtendedParams_Equal(ExtendedParam *ep1, ExtendedParam *ep2) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE ExtendedParam *ExtendedParam_FindByObject(Object *obj) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(856, obj != NULL);
return obj->extParam;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtendedParam_sub_4867B0(ExtendedParam *ep, Object *obj) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtendedParam_RemoveObjectSetAction(Object *object, void *refcon) {
object->extParam = NULL;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void EP_sub_48C850(ExtendedParam *ep, ObjectSet *objSet) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE ObjectSet *ExtendedParam_objectSet(ExtendedParam *ep) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(898, ep != NULL);
return ep->objectSet;
}
2023-01-11 23:26:04 +00:00
CW_INLINE uint32 ExtendedParam_sub_489110(ExtendedParam *ep) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(905, ep != NULL);
return ep->x4;
}
2023-01-11 23:26:04 +00:00
CW_INLINE ExtendedParamSet *AllocsExtParamSet_sub_4876C0(void) {
ExtendedParamSet *epList = IRO_malloc(sizeof(ExtendedParamSet));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(924, epList != NULL);
#ifdef IRO_DEBUG
epList->ep = NULL;
epList->otherEps = NULL;
#endif
return epList;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void FreesExtParamSet_sub_48CAE0(ExtendedParamSet *epList) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void InitsExtParamSet_sub_4876A0(ExtendedParamSet *epList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(948, epList != NULL);
epList->ep = NULL;
epList->otherEps = NULL;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void TermsExtParamSet_sub_48CB00(ExtendedParamSet *epList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(966, epList != NULL);
ExtendedParamSet_RemoveAll(epList);
#ifdef IRO_DEBUG
epList->ep = NULL;
epList->otherEps = NULL;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE void MaybeWalkExtParamSet_sub_48CBE0(ExtendedParamSet *epList, void (*action)(ExtendedParam *, void *), void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1010, epList != NULL);
IRO_ASSERT(1011, action != NULL);
while (epList && epList->ep) {
action(epList->ep, refcon);
epList = epList->otherEps;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE ExtendedParam *ExtParamSet_sub_4876D0(ExtendedParamSet *epList, ExtendedParam *ep) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtParamSet_sub_487660(ExtendedParamSet *epList, ExtendedParam *ep) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtParamSet_sub_487630(ExtendedParamSet *epList, ExtendedParam *ep) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1076, epList != NULL);
IRO_ASSERT(1077, ep != NULL);
if (!ExtParamSet_sub_4876D0(epList, ep))
ExtParamSet_sub_487660(epList, ep);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtendedParamSet_Remove(ExtendedParamSet *epList, ExtendedParam *ep) {
ExtendedParamSet *prev;
ExtendedParamSet *tmp;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1129, epList != NULL);
while (epList && epList->ep)
ExtendedParamSet_Remove(epList, epList->ep);
}
2023-01-11 23:26:04 +00:00
CW_INLINE PAHeapBlock *CreateUniqueHeapAlloc_sub_486420(void) {
PAHeapBlock *hb = IRO_malloc(sizeof(PAHeapBlock));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1225, hb != NULL);
#ifdef IRO_DEBUG
hb->parent = NULL;
#endif
return hb;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void InitUniqueHeapAlloc_sub_486410(PAHeapBlock *hb, IROLinear *nd) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1247, hb != NULL);
hb->x0 = nd;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean PAHeapBlocks_Equal(PAHeapBlock *hb1, PAHeapBlock *hb2) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1296, hb1 != NULL);
IRO_ASSERT(1297, hb2 != NULL);
return (hb1 == hb2) || (hb1->x0 == hb2->x0);
}
2023-01-11 23:26:04 +00:00
CW_INLINE PALocalVar *PALocalVar_New(void) {
PALocalVar *local = IRO_malloc(sizeof(PALocalVar));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1333, local != NULL);
#ifdef IRO_DEBUG
local->parent = NULL;
local->nextSibling = NULL;
#endif
return local;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PALocalVar_InitByObject(PALocalVar *local, Object *obj) {
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PALocalVar_InitByName(PALocalVar *local, char *name) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1372, local != NULL);
IRO_ASSERT(1373, name != NULL);
local->x0 = NULL;
local->x4 = IRO_malloc(strlen(name) + 1);
strcpy(local->x4, name);
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean PALocalVars_Equal(PALocalVar *local1, PALocalVar *local2) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PALocalVar_SetSth_sub_4847C0(PALocalVar *local, Object *obj) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1436, local != NULL);
IRO_ASSERT(1437, obj == NULL || obj != NULL);
local->x0 = obj;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Object *PALocalVar_Get0_sub_4847E0(PALocalVar *local) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1444, local != NULL);
return local->x0;
}
2023-01-11 23:26:04 +00:00
CW_INLINE char *PALocalVar_Get4_sub_4847D0(PALocalVar *local) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1451, local != NULL);
return local->x4;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PAMemoryBlock *PAMemoryBlock_New(void) {
PAMemoryBlock *mb = IRO_malloc(sizeof(PAMemoryBlock));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1491, mb != NULL);
#ifdef IRO_DEBUG
mb->kind = PAMEMORYBLOCKKIND_INVALID;
#endif
return mb;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PAMemoryBlock_Delete(PAMemoryBlock *mb) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1502, mb != NULL);
IRO_ASSERT(1503, mb->kind == PAMEMORYBLOCKKIND_INVALID);
IRO_free(mb);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PAMemoryBlock_Init(PAMemoryBlock *mb, PAMemoryBlockKind kind, void *thing) {
2023-01-10 11:05:21 +00:00
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:
2023-01-10 11:05:21 +00:00
CError_FATAL(1535);
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PAMemoryBlock_Term(PAMemoryBlock *mb) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1552, mb != NULL);
#ifdef IRO_DEBUG
mb->kind = PAMEMORYBLOCKKIND_INVALID;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean MemoryBlocks_Equal(PAMemoryBlock *mb1, PAMemoryBlock *mb2) {
2023-01-10 11:05:21 +00:00
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:
2023-01-10 11:05:21 +00:00
CError_FATAL(1684);
return 0;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE PAMemoryBlockKind PAMemoryBlock_kind(PAMemoryBlock *mb) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(1692, mb != NULL);
return mb->kind;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void *PAMemoryBlock_thing(PAMemoryBlock *mb) {
2023-01-10 11:05:21 +00:00
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:
2023-01-10 11:05:21 +00:00
CError_FATAL(1719);
return NULL;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSet *LocationSet_New(void) {
LocationSet *ls = IRO_malloc(sizeof(LocationSet));
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSet_Delete(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSet_InitKnown(LocationSet *ls, PAMemoryBlock *block, CInt64 field, UInt32 stride, Type *rtype) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSet_InitUnknown(LocationSet *ls, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) {
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSet_Copy(LocationSet *dest, LocationSet *src) {
2023-01-10 11:05:21 +00:00
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;
}
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSet_Term(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
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
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean LocationSets_Overlap(LocationSet *ls1, Type *rtype1, LocationSet *ls2, Type *rtype2) {
Boolean isUnknown1, isUnknown2;
PAMemoryBlock *restriction1, *restriction2;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean LocationSets_Equal(LocationSet *ls1, LocationSet *ls2) {
2023-01-10 11:05:21 +00:00
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)
);
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean LocationSets_LookupCompatible(LocationSet *ls1, LocationSet *ls2) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
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;
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean LocationSet_IsUnknown(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2233, ls != NULL);
return (ls == stUnknownLs) || (ls->block == stUnknownMb);
}
2023-01-11 23:26:04 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSet_SetRtype(LocationSet *ls, Type *rtype) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2263, ls != NULL);
IRO_ASSERT(2264, ls != stUnknownLs);
IRO_ASSERT(2265, rtype != NULL);
ls->rtype = rtype;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void SetsLocationSetField_sub_4851B0(LocationSet *ls, CInt64 field) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2272, ls != NULL);
IRO_ASSERT(2273, !LocationSet_IsUnknown(ls));
ls->u.known.field = field;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void SetsLocationSetStride_sub_4852D0(LocationSet *ls, SInt32 stride) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2280, ls != NULL);
IRO_ASSERT(2281, !LocationSet_IsUnknown(ls));
ls->u.known.stride = stride;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PAMemoryBlock *LocationSet_block(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2298, ls != NULL);
return ls->block;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Type *LocationSet_rtype(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2306, ls != NULL);
IRO_ASSERT(2307, ls != stUnknownLs);
return ls->rtype;
}
2023-01-11 23:26:04 +00:00
CW_INLINE CInt64 LocationSet_field(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2314, ls != NULL);
IRO_ASSERT(2315, !LocationSet_IsUnknown(ls));
return ls->u.known.field;
}
2023-01-11 23:26:04 +00:00
CW_INLINE UInt32 LocationSet_stride(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2322, ls != NULL);
IRO_ASSERT(2323, !LocationSet_IsUnknown(ls));
return ls->u.known.stride;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PAMemoryBlock *LocationSet_restriction(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2330, ls != NULL);
IRO_ASSERT(2331, LocationSet_IsUnknown(ls));
return ls->u.unknown.restriction;
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSet *LocationSet_bitfieldOf(LocationSet *ls) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2338, ls != NULL);
IRO_ASSERT(2339, LocationSet_IsUnknown(ls));
return ls->u.unknown.bitfieldOf;
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSetSet *LocationSetSet_New(void) {
LocationSetSet *lss = IRO_malloc(sizeof(LocationSetSet));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2356, lss != NULL);
#ifdef IRO_DEBUG
lss->loc = NULL;
lss->otherLocs = NULL;
lss->count = 0;
#endif
return lss;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_Delete(LocationSetSet *lss) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_Init(LocationSetSet *lss) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2382, lss != NULL);
lss->loc = NULL;
lss->otherLocs = NULL;
lss->count = 0;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_Copy(LocationSetSet *dest, LocationSetSet *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2391, dest != NULL);
IRO_ASSERT(2392, src != NULL);
dest->loc = NULL;
dest->otherLocs = NULL;
dest->count = 0;
LocationSetSet_AddSet(dest, src);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_Term(LocationSetSet *lss) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2402, lss != NULL);
LocationSetSet_RemoveAll(lss);
#ifdef IRO_DEBUG
lss->loc = NULL;
lss->otherLocs = NULL;
lss->count = 0;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_ForEach(LocationSetSet *lss, void (*action)(LocationSet *, void *), void *refcon) {
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSet *LocationSetSet_Find(LocationSetSet *lss, LocationSet *ls) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSet *LocationSetSet_FindUnknown(LocationSetSet *lss) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSet *LocationSetSet_FindFirst(LocationSetSet *lss) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2498, lss != NULL);
return lss->loc;
}
2023-01-11 23:26:04 +00:00
CW_INLINE int LocationSetSet_Count(LocationSetSet *lss) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2505, lss != NULL);
return lss->count;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_RemoveAllWithMemoryBlock(LocationSetSet *lss, PAMemoryBlock *block) {
LocationSetSet *first;
LocationSetSet *prev;
LocationSetSet *next;
LocationSetSet *tmp;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_SimpleAdd(LocationSetSet *lss, LocationSet *ls) {
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_Add(LocationSetSet *lss, LocationSet *ls) {
2023-01-10 11:05:21 +00:00
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);
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_AddUnknown(LocationSetSet *lss, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) {
LocationSet *ls;
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_Remove(LocationSetSet *lss, LocationSet *ls) {
LocationSetSet *prev;
LocationSetSet *first;
LocationSetSet *tmp;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_RemoveAll(LocationSetSet *lss) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2707, lss != NULL);
while (lss && lss->loc)
LocationSetSet_Remove(lss, lss->loc);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_AddSetAction(LocationSet *ls, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2717, ls != NULL);
IRO_ASSERT(2718, refcon != NULL);
LocationSetSet_Add((LocationSetSet *) refcon, ls);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_SimpleAddSetAction(LocationSet *ls, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2725, ls != NULL);
IRO_ASSERT(2726, refcon != NULL);
LocationSetSet_SimpleAdd((LocationSetSet *) refcon, ls);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_RemoveSetAction(LocationSet *ls, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2744, ls != NULL);
IRO_ASSERT(2745, refcon != NULL);
LocationSetSet_Remove((LocationSetSet *) refcon, ls);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void LocationSetSet_sub_488700(LocationSetSet *dest, LocationSetSet *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2752, dest != NULL);
IRO_ASSERT(2753, src != NULL);
LocationSetSet_ForEach(src, LocationSetSet_RemoveSetAction, dest);
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean LocationSetSets_Equal(LocationSetSet *lss1, LocationSetSet *lss2) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE ParamMapping *ParamMapping_New(void) {
ParamMapping *pm = IRO_malloc(sizeof(ParamMapping));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2885, pm != NULL);
#ifdef IRO_DEBUG
pm->actual = NULL;
pm->formal = NULL;
pm->extended = NULL;
#endif
return pm;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMapping_Delete(ParamMapping *pm) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMapping_Init_PROBABLY(ParamMapping *pm, IROLinear *actual, Object *formal, ExtendedParam *extended) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2911, pm != NULL);
pm->actual = actual;
pm->formal = formal;
pm->extended = extended;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMapping_Copy(ParamMapping *dest, ParamMapping *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2920, src != NULL);
IRO_ASSERT(2921, dest != NULL);
dest->actual = src->actual;
dest->formal = src->formal;
dest->extended = src->extended;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMapping_Term(ParamMapping *pm) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2933, pm != NULL);
#ifdef IRO_DEBUG
pm->actual = NULL;
pm->formal = NULL;
pm->extended = NULL;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMapping_SetExtended(ParamMapping *pm, ExtendedParam *ep) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2992, pm != NULL);
pm->extended = ep;
}
2023-01-11 23:26:04 +00:00
CW_INLINE IROLinear *ParamMapping_actual(ParamMapping *pm) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(2999, pm != NULL);
return pm->actual;
}
2023-01-11 23:26:04 +00:00
CW_INLINE ExtendedParam *ParamMapping_extended(ParamMapping *pm) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3011, pm != NULL);
return pm->extended;
}
2023-01-11 23:26:04 +00:00
CW_INLINE ParamMappingFunction *ParamMappingFunction_New(void) {
ParamMappingFunction *pmf = IRO_malloc(sizeof(ParamMappingFunction));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3026, pmf != NULL);
#ifdef IRO_DEBUG
pmf->mapping = NULL;
pmf->otherMappings = NULL;
#endif
return pmf;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMappingFunction_Delete(ParamMappingFunction *pmf) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMappingFunction_Init(ParamMappingFunction *pmf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3050, pmf != NULL);
pmf->mapping = NULL;
pmf->otherMappings = NULL;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMappingFunction_Copy(ParamMappingFunction *dest, ParamMappingFunction *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3058, src != NULL);
IRO_ASSERT(3059, dest != NULL);
dest->mapping = NULL;
dest->otherMappings = NULL;
ParamMappingFunction_AddAllMaybe_sub_487C50(dest, src);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMappingFunction_Term(ParamMappingFunction *pmf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3068, pmf != NULL);
ParamMappingFunction_RemoveAll(pmf);
#ifdef IRO_DEBUG
pmf->mapping = NULL;
pmf->otherMappings = NULL;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE void pmf_sub_487C70(ParamMappingFunction *pmf, void (*action)(ParamMapping *, void *), void *refcon) {
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE ParamMapping *ParamMappingFunction_FindMappingByFormal(ParamMappingFunction *pmf, Object *formal) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void Pmf_Add_sub_486610(ParamMappingFunction *pmf, ParamMapping *mapping) {
ParamMapping *existing;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMappingFunction_Remove(ParamMappingFunction *pmf, ParamMapping *mapping) {
ParamMappingFunction *prev;
ParamMappingFunction *tmp;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMappingFunction_RemoveAll(ParamMappingFunction *pmf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3213, pmf != NULL);
while (pmf && pmf->mapping)
ParamMappingFunction_Remove(pmf, pmf->mapping);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMappingFunction_AddFunctionAction(ParamMapping *mapping, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3223, mapping != NULL);
IRO_ASSERT(3224, refcon != NULL);
Pmf_Add_sub_486610((ParamMappingFunction *) refcon, mapping);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *dest, ParamMappingFunction *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3231, dest != NULL);
IRO_ASSERT(3232, src != NULL);
pmf_sub_487C70(src, ParamMappingFunction_AddFunctionAction, dest);
}
2023-01-11 23:26:04 +00:00
CW_INLINE PointsToEntry *PointsToEntry_New(void) {
PointsToEntry *pte = IRO_malloc(sizeof(PointsToEntry));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3288, pte != NULL);
#ifdef IRO_DEBUG
pte->loc = NULL;
pte->locs = NULL;
#endif
return pte;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToEntry_Delete(PointsToEntry *pte) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToEntry_Init(PointsToEntry *pte, LocationSet *loc, LocationSetSet *locs) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToEntry_Copy(PointsToEntry *dest, PointsToEntry *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3325, src != NULL);
IRO_ASSERT(3326, dest != NULL);
PointsToEntry_Init(dest, src->loc, src->locs);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToEntry_Term(PointsToEntry *pte) {
2023-01-10 11:05:21 +00:00
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
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean PointsToEntries_Equal(PointsToEntry *pte1, PointsToEntry *pte2) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSet *PointsToEntry_loc(PointsToEntry *pte) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3407, pte != NULL);
return pte->loc;
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSetSet *PointsToEntry_locs(PointsToEntry *pte) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3414, pte != NULL);
return pte->locs;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PointsToFunction *PointsToFunction_New(void) {
PointsToFunction *pointsToFunc = IRO_malloc(sizeof(PointsToFunction));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3430, pointsToFunc != NULL);
#ifdef IRO_DEBUG
pointsToFunc->pte = NULL;
pointsToFunc->otherPtes = NULL;
#endif
return pointsToFunc;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_Delete(PointsToFunction *pointsToFunc) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_Init(PointsToFunction *pointsToFunc) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3454, pointsToFunc != NULL);
pointsToFunc->pte = NULL;
pointsToFunc->otherPtes = NULL;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_Copy(PointsToFunction *dest, PointsToFunction *src) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3462, src != NULL);
IRO_ASSERT(3463, dest != NULL);
dest->pte = NULL;
dest->otherPtes = NULL;
PointsToFunction_AddAllIGuess_sub_487D80(dest, src);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_Term(PointsToFunction *pointsToFunc) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3472, pointsToFunc != NULL);
PointsToFunction_RemoveAll(pointsToFunc);
#ifdef IRO_DEBUG
pointsToFunc->pte = NULL;
pointsToFunc->otherPtes = NULL;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_ForEach(PointsToFunction *pointsToFunc, void (*action)(PointsToEntry *, void *), void *refcon) {
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE PointsToEntry *PointsToFunction_FindByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PointsToEntry *PointsToFunction_FindFirst(PointsToFunction *pointsToFunc) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3539, pointsToFunc != NULL);
return pointsToFunc->pte;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PointsToEntry *PointsToFunction_FindByLookupCompatibleLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PointsToEntry *PointsToFunction_FindContainingLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls, Type *rtype) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_RemoveOverlappingLocations(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
Type *rtype1;
Type *rtype2;
LocationSet *ls;
PointsToFunction *prev;
PointsToFunction *next;
PointsToFunction *tmp;
2023-01-10 11:05:21 +00:00
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;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
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;
2023-01-10 11:05:21 +00:00
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;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean PointsToFunction_SimpleAdd(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
PointsToEntry *newPTE;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean PointsToFunction_Add(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean PointsToFunction_AddWithoutChecking(PointsToFunction *pointsToFunc, PointsToEntry *pte) {
LocationSet *ls;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_RemoveByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) {
PointsToFunction *prev;
PointsToFunction *tmp;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_RemoveAll(PointsToFunction *pointsToFunc) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3862, pointsToFunc != NULL);
while (pointsToFunc && pointsToFunc->pte)
PointsToFunction_RemoveByLocationSet(pointsToFunc, pointsToFunc->pte->loc);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_AddFunctionAction(PointsToEntry *pte, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3872, pte != NULL);
IRO_ASSERT(3873, refcon != NULL);
PointsToFunction_Add((PointsToFunction *) refcon, pte);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_SimpleAddFunctionAction(PointsToEntry *pte, void *refcon) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(3880, pte != NULL);
IRO_ASSERT(3881, refcon != NULL);
PointsToFunction_SimpleAdd((PointsToFunction *) refcon, pte);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PointsToFunction_AddAllIGuess_sub_487D80(PointsToFunction *dest, PointsToFunction *src) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean PointsToFunctions_Equal(PointsToFunction *pointsToFunc1, PointsToFunction *pointsToFunc2) {
PointsToFunction *scan;
PointsToEntry *pte;
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE Boolean PointsToFunctions_Match(PointsToFunction *pointsToFunc1, PointsToFunction *pointsToFunc2) {
return 1;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PartialTransferFunction *PartialTransferFunction_New(void) {
PartialTransferFunction *ptf = IRO_malloc(sizeof(PartialTransferFunction));
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PartialTransferFunction_Delete(PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PartialTransferFunction_Init(PartialTransferFunction *ptf, IROLinear *contextNd, PartialTransferFunction *contextPTF) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PartialTransferFunction_Copy(PartialTransferFunction *dest, PartialTransferFunction *src) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PartialTransferFunction_Term(PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
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
}
2023-01-11 23:26:04 +00:00
CW_INLINE PointsToFunction *PartialTransferFunction_initialPointsToFn(PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4221, ptf != NULL);
return ptf->initialPointsToFn;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PointsToFunction *PartialTransferFunction_finalPointsToFn(PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4227, ptf != NULL);
return ptf->finalPointsToFn;
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSetSet *PTF_sub_48D750(PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4233, ptf != NULL);
return ptf->funcModifies;
}
2023-01-11 23:26:04 +00:00
CW_INLINE LocationSet *PartialTransferFunction_returnLocation(PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE IROLinear *PTF_sub_48B980(PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4265, ptf != NULL);
return ptf->context.nd;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PartialTransferFunction *PTF_sub_48B970(PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4271, ptf != NULL);
return ptf->context.ptf;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PartialTransferFunction_sub_48A610(PartialTransferFunction *ptf, Boolean value) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4298, ptf != NULL);
ptf->x10 = (value != 0) ? 1 : 0;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PTFList *PTFList_New(void) {
PTFList *ptfList = IRO_malloc(sizeof(PTFList));
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4393, ptfList != NULL);
#ifdef IRO_DEBUG
ptfList->ptf = NULL;
ptfList->otherPTFs = NULL;
#endif
return ptfList;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PTFList_Delete(PTFList *ptfList) {
2023-01-10 11:05:21 +00:00
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);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PTFList_Init(PTFList *ptfList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4417, ptfList != NULL);
ptfList->ptf = NULL;
ptfList->otherPTFs = NULL;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PTFList_Term(PTFList *ptfList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4435, ptfList != NULL);
PTFList_RemoveAll(ptfList);
#ifdef IRO_DEBUG
ptfList->ptf = NULL;
ptfList->otherPTFs = NULL;
#endif
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PTFList_ForEach(PTFList *ptfList, void (*action)(PartialTransferFunction *, void *), void *refcon) {
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE PartialTransferFunction *PTFList_sub_48A0F0(PTFList *ptfList, PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE PartialTransferFunction *PTFList_FindFirst(PTFList *ptfList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4502, ptfList != NULL);
return ptfList->ptf;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PTFList_sub_48A080(PTFList *ptfList, PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
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;
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PTFList_sub_48A050(PTFList *ptfList, PartialTransferFunction *ptf) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4529, ptfList != NULL);
IRO_ASSERT(4530, ptf != NULL);
if (!PTFList_sub_48A0F0(ptfList, ptf))
PTFList_sub_48A080(ptfList, ptf);
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PTFList_Remove(PTFList *ptfList, PartialTransferFunction *ptf) {
PTFList *prev;
PTFList *tmp;
2023-01-10 11:05:21 +00:00
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;
}
}
2023-01-11 23:26:04 +00:00
CW_INLINE void PTFList_RemoveAll(PTFList *ptfList) {
2023-01-10 11:05:21 +00:00
IRO_ASSERT(4582, ptfList != NULL);
while (ptfList && ptfList->ptf)
PTFList_Remove(ptfList, ptfList->ptf);
}