summaryrefslogtreecommitdiff
path: root/compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c')
-rw-r--r--compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c2736
1 files changed, 2736 insertions, 0 deletions
diff --git a/compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c b/compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c
new file mode 100644
index 0000000..dad9501
--- /dev/null
+++ b/compiler_and_linker/FrontEnd/Optimizer/IroPointerAnalysisADTs.c
@@ -0,0 +1,2736 @@
+#include "IroPointerAnalysis.h"
+#include "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(3818, pointsToFunc != NULL);
+ IRO_ASSERT(3819, ls != NULL);
+ IRO_ASSERT(3820, !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);
+}