1// { dg-do compile } 2// { dg-options "-fgnu-tm -O2 -fdump-tree-optimized" } 3 4typedef __SIZE_TYPE__ size_t; 5extern void *malloc(size_t); 6 7namespace bench 8{ 9 class LLNode 10 { 11 LLNode* next; 12 int data; 13 14 public: 15 __attribute__((transaction_safe)) 16 LLNode(int val, LLNode* m_next) 17 { 18 data = val; 19 next = m_next; 20 } 21 __attribute__((transaction_safe)) 22 ~LLNode(){} 23 __attribute__((transaction_safe)) 24 int get_val() {return data;} 25 __attribute__((transaction_safe)) 26 LLNode* get_next() {return next;} 27 __attribute__((transaction_safe)) 28 void set_val(int val) {data = val;} 29 __attribute__((transaction_safe)) 30 void set_next(LLNode* n) {next = n;} 31 __attribute__((transaction_safe)) 32 void *operator new(size_t size); 33 }; 34 35 class LinkedList 36 { 37 LLNode* head; 38 public: 39 LinkedList(); 40 void insert(int val); 41 }; 42} 43 44using bench::LinkedList; 45using bench::LLNode; 46 47 48__attribute__((transaction_safe)) 49void* LLNode::operator new(size_t size) 50{ 51 return malloc(size); 52} 53 54LinkedList::LinkedList() : head(new LLNode(-1, 0)) { } 55 56void LinkedList::insert(int val) 57{ 58 __transaction_atomic { 59 LLNode* prev = head; 60 LLNode* curr = head->get_next(); 61 62 while (curr != 0) { 63 if (curr->get_val() >= val) 64 break; 65 prev = curr; 66 curr = prev->get_next(); 67 } 68 69 if (!curr || (curr->get_val() > val)){ 70 LLNode* tmp = new LLNode(val,curr); 71 prev->set_next(tmp); 72 } 73 } 74} 75 76// Make sure we don't do tail optimization on the commit, except on 77// the uninstrumented code path. 78// { dg-final { scan-tree-dump-times "commitTransaction...; .tail call" 1 "optimized" } } 79// { dg-final { cleanup-tree-dump "optimized" } } 80 81