1/* { dg-do compile } */
2/* { dg-options "-fgnu-tm -O3" } */
3
4/* The function calculateCircumCircle() should get inlined into the TM
5   clone for TMelement_alloc(), so we don't need to generate a TM
6   clone for calculateCircumCircle().  We also don't need to put its
7   entry into the clone table since it's static.  */
8
9/* { dg-final { scan-assembler-not "ZGTt21calculateCircumCircle" } } */
10
11extern double sqrt(double) __attribute__((transaction_pure));
12extern void *xmalloc(int) __attribute__((transaction_safe));
13
14typedef struct coordinate {
15    double x;
16    double y;
17} coordinate_t;
18typedef struct element {
19    coordinate_t coordinates[3];
20    long numCoordinate;
21    coordinate_t circumCenter;
22    double circumRadius;
23} element_t;
24
25__attribute__((transaction_safe))
26double
27coordinate_distance (coordinate_t* coordinatePtr, coordinate_t* aPtr)
28{
29    return sqrt( coordinatePtr->x );
30}
31
32__attribute__((transaction_safe))
33static void
34calculateCircumCircle (element_t* elementPtr)
35{
36    long numCoordinate = elementPtr->numCoordinate;
37    coordinate_t* coordinates = elementPtr->coordinates;
38    coordinate_t* circumCenterPtr = &elementPtr->circumCenter;
39    ((void) (0));
40    if (numCoordinate == 2) {
41	circumCenterPtr->x = (coordinates[0].x + coordinates[1].x) / 2.0;
42	circumCenterPtr->y = (coordinates[0].y + coordinates[1].y) / 2.0;
43    }
44 else {
45	double ax = coordinates[0].x;
46	double ay = coordinates[0].y;
47	double bx = coordinates[1].x;
48	double by = coordinates[1].y;
49	double cx = coordinates[2].x;
50	double cy = coordinates[2].y;
51	double bxDelta = bx - ax;
52	double byDelta = by - ay;
53	double cxDelta = cx - ax;
54	double cyDelta = cy - ay;
55	double bDistance2 = (bxDelta * bxDelta) + (byDelta * byDelta);
56	double cDistance2 = (cxDelta * cxDelta) + (cyDelta * cyDelta);
57	double xNumerator = (byDelta * cDistance2) - (cyDelta * bDistance2);
58	double yNumerator = (bxDelta * cDistance2) - (cxDelta * bDistance2);
59	double denominator = 2 * ((bxDelta * cyDelta) - (cxDelta * byDelta));
60	double rx = ax - (xNumerator / denominator);
61	double ry = ay + (yNumerator / denominator);
62	circumCenterPtr->x = rx;
63	circumCenterPtr->y = ry;
64    }
65    elementPtr->circumRadius = coordinate_distance(circumCenterPtr,
66						   &coordinates[0]);
67}
68
69element_t*
70element_alloc (coordinate_t* coordinates, long numCoordinate)
71{
72    element_t* elementPtr;
73    elementPtr = (element_t*)xmalloc(sizeof(element_t));
74    if (elementPtr) {
75	calculateCircumCircle(elementPtr);
76    }
77    return elementPtr;
78}
79
80__attribute__((transaction_safe))
81element_t*
82TMelement_alloc (coordinate_t* coordinates, long numCoordinate)
83{
84    element_t* elementPtr;
85    elementPtr = (element_t*)xmalloc(sizeof(element_t));
86    if (elementPtr) {
87	calculateCircumCircle(elementPtr);
88    }
89    return elementPtr;
90}
91