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
      27  coordinate_distance (coordinate_t* coordinatePtr, coordinate_t* aPtr)
      28  {
      29      return sqrt( coordinatePtr->x );
      30  }
      31  
      32  __attribute__((transaction_safe))
      33  static void
      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*
      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*
      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  }