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 
11 extern double sqrt(double) __attribute__((transaction_pure));
12 extern void *xmalloc(int) __attribute__((transaction_safe));
13 
14 typedef struct coordinate {
15     double x;
16     double y;
17 } coordinate_t;
18 typedef 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))
26 double
coordinate_distance(coordinate_t * coordinatePtr,coordinate_t * aPtr)27 coordinate_distance (coordinate_t* coordinatePtr, coordinate_t* aPtr)
28 {
29     return sqrt( coordinatePtr->x );
30 }
31 
32 __attribute__((transaction_safe))
33 static void
calculateCircumCircle(element_t * elementPtr)34 calculateCircumCircle (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 
69 element_t*
element_alloc(coordinate_t * coordinates,long numCoordinate)70 element_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))
81 element_t*
TMelement_alloc(coordinate_t * coordinates,long numCoordinate)82 TMelement_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