diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ipa.c | 24 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr45679-1_0.C | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr45679-1_1.C | 77 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr45679-2_0.C | 119 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lto/pr45679-2_1.C | 100 | ||||
-rw-r--r-- | gcc/tree-inline.c | 3 |
9 files changed, 359 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 27e365fc7b5..72f359191e5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-09-16 Jan Hubicka <jh@suse.cz> + + * lto-cgraph.c (lto_output_node): Fix handling of clones. + * ipa.c (cgraph_remove_unreachabloe_nodes): Fix handling of + unreachable clones with reachable clones. + * tree-inline.c (copy_bb): Fix sanity checking when producing + unreachable clone. + 2010-09-16 Anatoly Sokolov <aesok@post.ru> * config/m32r/m32r.c (TARGET_MEMORY_MOVE_COSTS): Remove. diff --git a/gcc/ipa.c b/gcc/ipa.c index 48e331e9b77..8c0ca86d59d 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -407,22 +407,26 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) if (!clone) { cgraph_release_function_body (node); - node->analyzed = false; node->local.inlinable = false; + if (node->prev_sibling_clone) + node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone; + else if (node->clone_of) + node->clone_of->clones = node->next_sibling_clone; + if (node->next_sibling_clone) + node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone; +#ifdef ENABLE_CHECKING + if (node->clone_of) + node->former_clone_of = node->clone_of->decl; +#endif + node->clone_of = NULL; + node->next_sibling_clone = NULL; + node->prev_sibling_clone = NULL; } else gcc_assert (!clone->in_other_partition); + node->analyzed = false; cgraph_node_remove_callees (node); ipa_remove_all_references (&node->ref_list); - if (node->prev_sibling_clone) - node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone; - else if (node->clone_of) - node->clone_of->clones = node->next_sibling_clone; - if (node->next_sibling_clone) - node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone; - node->clone_of = NULL; - node->next_sibling_clone = NULL; - node->prev_sibling_clone = NULL; } else cgraph_remove_node (node); diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 78c809b5520..5410e8fcbc5 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -447,11 +447,14 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, clone_of = node->clone_of; while (clone_of - && (ref = lto_cgraph_encoder_lookup (encoder, node->clone_of)) == LCC_NOT_FOUND) + && (ref = lto_cgraph_encoder_lookup (encoder, clone_of)) == LCC_NOT_FOUND) if (clone_of->prev_sibling_clone) clone_of = clone_of->prev_sibling_clone; else clone_of = clone_of->clone_of; + + if (LTO_cgraph_analyzed_node) + gcc_assert (clone_of || !node->clone_of); if (!clone_of) lto_output_sleb128_stream (ob->main_stream, LCC_NOT_FOUND); else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 163079a253b..caceb8f9faa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2010-09-16 Jan Hubicka <jh@suse.cz> + + * g++.dg/lto/pr45679-1_0.C: New file. + * g++.dg/lto/pr45679-1_1.C: New file. + * g++.dg/lto/pr45679-0_0.C: New file. + * g++.dg/lto/pr45679-0_1.C: New file. + 2010-09-16 Janus Weil <janus@gcc.gnu.org> PR fortran/45674 diff --git a/gcc/testsuite/g++.dg/lto/pr45679-1_0.C b/gcc/testsuite/g++.dg/lto/pr45679-1_0.C new file mode 100644 index 00000000000..05f7b550d4d --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr45679-1_0.C @@ -0,0 +1,28 @@ +// { dg-lto-do link } +// { dg-lto-options {{-O3 -Wno-multichar}} } +// { dg-extra-ld-options "-fwhopr -r -nostdlib" } + + extern "C" { + typedef struct __locale_struct { + } + *__locale_t; + } + typedef void * POVMSContext; + struct POVMSData { + }; + int POVMS_OpenContext (POVMSContext *contextrefptr); + enum { + kPOVMsgIdent_InitInfo = 'InIn', kPOVMsgIdent_RenderOptions = 'ROpt', kPOVMsgIdent_RenderAll = 'RAll', kPOVMsgIdent_RenderArea = 'RAre', kPOVMsgIdent_RenderPause = 'RPau', kPOVMsgIdent_RenderStop = 'RSto', kPOVMsgIdent_RenderStarted = 'RRun', kPOVMsgIdent_RenderDone = 'REnd', kPOVMsgIdent_FrameStatistics = 'FSta', kPOVMsgIdent_ParseStatistics = 'PSta', kPOVMsgIdent_RenderStatistics = 'RSta', kPOVMsgIdent_Progress = 'Prog', kPOVMsgIdent_Warning = 'Warn', kPOVMsgIdent_Error = 'ErrW', kPOVMsgIdent_FatalError = 'ErrF', kPOVMsgIdent_Debug = 'Dbug' }; + namespace pov { + } + using namespace pov; + namespace pov { + int pre_init_flag = 0; + } + POVMSContext POVMS_Render_Context = __null; + void povray_init() { + if (pre_init_flag == 0) { + int err; + err = POVMS_OpenContext(&POVMS_Render_Context); + } + } diff --git a/gcc/testsuite/g++.dg/lto/pr45679-1_1.C b/gcc/testsuite/g++.dg/lto/pr45679-1_1.C new file mode 100644 index 00000000000..c5e2db061fb --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr45679-1_1.C @@ -0,0 +1,77 @@ + extern "C" { + typedef struct _IO_FILE FILE; + extern struct _IO_FILE *stderr; + extern int fprintf (FILE *__restrict __stream, __const char *__restrict __format, ...); + } + enum { + kPOVMSObjectClassID = 'OCLA', kPOVMSMessageClassID = 'MCLA', kPOVMSMessageIdentID = 'MIDE', kPOVMSSourceAddressID = 'MSRC', kPOVMSDestinationAddressID = 'MDST', kPOVMSMessageTimeoutID = 'TOUT', kPOVMSMessageErrorID = 'MERR' }; + typedef void * POVMSContext; + typedef struct POVMSData POVMSObject, *POVMSObjectPtr; + typedef struct POVMSData POVMSAttribute, *POVMSAttributePtr; + struct POVMSData { + union { + struct POVMSNode *root; + }; + }; + struct POVMSNode { + struct POVMSNode *next; + unsigned int key; + struct POVMSData data; + }; + int POVMSObject_New (POVMSObjectPtr object, unsigned int objclass); + int POVMSObject_Set (POVMSObjectPtr object, POVMSAttributePtr attr, unsigned int key); + int POVMSAttr_Copy (POVMSAttributePtr sourceattr, POVMSAttributePtr destattr); + int POVMSUtil_GetType (POVMSObjectPtr object, unsigned int key, unsigned int *typevalue); + namespace pov_base { + enum { + kNoError = 0, kNoErr = kNoError, kParamErr = -1, kMemFullErr = -2, kOutOfMemoryErr = kMemFullErr, kInvalidDataSizeErr = -3, kCannotHandleDataErr = -4, kNullPointerErr = -5, kChecksumErr = -6, kParseErr = -7, kCannotOpenFileErr = -8, kInvalidDestAddrErr = -9, kCannotConnectErr = -10, kDisconnectedErr = -11, kHostDisconnectedErr = -12, kNetworkDataErr = -13, kNetworkConnectionErr = -14, kObjectAccessErr = -15, kVersionErr = -16, kFileDataErr = -17, kAuthorisationErr = -18, kDataTypeErr = -19, kTimeoutErr = -20, kInvalidContextErr = -21 }; + } + using namespace pov_base; + struct POVMSContextData { + }; + int POVMS_AssertFunction (int cond, const char *str, const char *filename, int line); + int POVMS_OpenContext(POVMSContext *contextrefptr) { + POVMSContextData *context = __null; + if(contextrefptr == __null) return kParamErr; + if(POVMS_AssertFunction(context != __null, "POVMS_Open_Context failed, out of memory", "povms.cpp", 283) == false) return kMemFullErr; + return kNoErr; + } + int POVMS_AssertFunction(int cond, const char *str, const char *filename, int line) { + if(cond == false) { + fprintf(stderr, "POVMS_ASSERT failed in %s line %d: %s\n", filename, (int)line, str); + } + } + int POVMSObject_Copy(POVMSObjectPtr sourceobject, POVMSObjectPtr destobject) { + POVMSNode *cur = __null; + POVMSAttribute attr; + unsigned int t; + int ret = kNoErr; + if(sourceobject == destobject) return kParamErr; + if(POVMSUtil_GetType(sourceobject, kPOVMSObjectClassID, &t) != kNoErr) return kObjectAccessErr; + if(POVMSObject_New(destobject, t) != kNoErr) return kObjectAccessErr; + for(cur = sourceobject->root; + cur != __null; + cur = cur->next) { + if(POVMS_AssertFunction(POVMSAttr_Copy(&(cur->data), &attr) == kNoErr, "POVMSObject_Copy failed, out of memory", "povms.cpp", 2028) == false) { + } + if(POVMS_AssertFunction(POVMSObject_Set(destobject, &attr, cur->key) == kNoErr, "POVMSObject_Copy failed, out of memory", "povms.cpp", 2034) == false) { + } + } + return ret; + } + int POVMSObject_Merge(POVMSObjectPtr sourceobject, POVMSObjectPtr destobject) { + POVMSNode *cur = __null; + POVMSAttribute attr; + unsigned int t1, t2; + int ret = kNoErr; + if(destobject == __null) return kParamErr; + if(POVMSUtil_GetType(sourceobject, kPOVMSObjectClassID, &t1) != kNoErr) return kObjectAccessErr; + if(POVMSUtil_GetType(sourceobject, kPOVMSObjectClassID, &t2) != kNoErr) return kObjectAccessErr; + for(cur = sourceobject->root; + cur != __null; + cur = cur->next) { + if(POVMS_AssertFunction(POVMSObject_Set(destobject, &attr, cur->key) == kNoErr, "POVMSObject_Merge failed, out of memory", "povms.cpp", 2090) == false) { + } + } + return ret; + } diff --git a/gcc/testsuite/g++.dg/lto/pr45679-2_0.C b/gcc/testsuite/g++.dg/lto/pr45679-2_0.C new file mode 100644 index 00000000000..dcc53a63eb8 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr45679-2_0.C @@ -0,0 +1,119 @@ +// { dg-lto-do link } +// { dg-lto-options {{-O3 -Wno-multichar}} } +// { dg-extra-ld-options "-fwhopr -r -nostdlib" } + extern "C" { + typedef struct { + union { + } + __value; + } + __mbstate_t; + struct _IO_marker { + }; + extern "C" { + } + }; + namespace pov_base { + class IOBase { + }; + } + namespace pov { + typedef double VECTOR[3]; + enum { + X = 0, Y = 1, Z = 2, T = 3 }; + inline void Assign_Vector(VECTOR d, VECTOR s) { + } + typedef float BBOX_VAL; + typedef BBOX_VAL BBOX_VECT[3]; + typedef struct Bounding_Box_Struct BBOX; + struct Bounding_Box_Struct { + }; + inline void Make_BBox_from_min_max(BBOX& BBox, BBOX_VECT mins, BBOX_VECT maxs) { + } + typedef long long COUNTER; + inline double DBL_Counter(COUNTER x) { + } + struct Image_Struct { + union { + } + data; + }; + struct Density_file_Data_Struct { + union { + } + Vals; + }; + struct Pigment_Struct { + union { + struct { + } + Brick; + struct { + } + Fractal; + struct { + } + Function; + } + Vals; + }; + typedef enum shelltype { + PRE_SCENE_SHL = 0, PRE_FRAME_SHL, POST_FRAME_SHL, POST_SCENE_SHL, USER_ABORT_SHL, FATAL_SHL, MAX_SHL } + SHELLRET; + } + typedef void * POVMSContext; + struct POVMSData { + }; + int POVMS_OpenContext (POVMSContext *contextrefptr); + namespace pov_base { + enum { + kFalseErr = 1, kOutOfSyncErr = 2, kNotNowErr = kOutOfSyncErr, kQueueFullErr = 3 }; + } + namespace pov_base { + class OTextStream { + }; + } + enum { + kPOVMsgClass_RenderControl = 'Ctrl', kPOVMsgClass_RenderOutput = 'Outp', kPOVMsgClass_IniOptions = 'IniO', kPOVMsgClass_Miscellaneous = 'Misc' }; + namespace pov_base { + class PlatformBase { + }; + } + class POVMS_Container { + template<class T> void Read(T& stream) { + } + }; + class POVMS_MessageReceiver { + private: class HandlerOO { + }; + protected: template<class T> class MemberHandlerOO : public HandlerOO { + }; + class FunctionHandlerOO : public HandlerOO { + }; + template<class T> void InstallFront(unsigned int hclass, unsigned int hid, T *cptr, typename MemberHandlerOO<T>::MemberHandlerPtr hptr) { + } + }; + namespace pov_base { + class TextStreamBuffer { + }; + } + namespace pov_frontend { + using namespace pov_base; + class MessageOutput : public POVMS_MessageReceiver { + }; + class DefaultPlatformBase : public PlatformBase { + }; + } + using namespace pov; + namespace pov { + int pre_init_flag = 0; + } + POVMSContext POVMS_Render_Context = __null; + int main(int argc, char **argv) { + } + void povray_init() { + if (pre_init_flag == 0) { + int err; + err = POVMS_OpenContext(&POVMS_Render_Context); + } + } diff --git a/gcc/testsuite/g++.dg/lto/pr45679-2_1.C b/gcc/testsuite/g++.dg/lto/pr45679-2_1.C new file mode 100644 index 00000000000..23ba08aecfc --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr45679-2_1.C @@ -0,0 +1,100 @@ +extern "C" { + typedef struct __locale_struct { + } + *__locale_t; + union wait { + }; + extern "C" { + } + typedef struct _IO_FILE FILE; + typedef struct { + union { + } + __value; + } + _G_fpos64_t; + struct _IO_marker { + } + _IO_cookie_io_functions_t; + extern struct _IO_FILE *stderr; + extern int fprintf (FILE *__restrict __stream, __const char *__restrict __format, ...); + } + enum { + kPOVMSObjectClassID = 'OCLA', kPOVMSMessageClassID = 'MCLA', kPOVMSMessageIdentID = 'MIDE', kPOVMSSourceAddressID = 'MSRC', kPOVMSDestinationAddressID = 'MDST', kPOVMSMessageTimeoutID = 'TOUT', kPOVMSMessageErrorID = 'MERR' }; + typedef void * POVMSContext; + typedef struct POVMSData POVMSObject, *POVMSObjectPtr; + typedef struct POVMSData POVMSAttribute, *POVMSAttributePtr; + typedef struct POVMSData POVMSAttributeList, *POVMSAttributeListPtr; + struct POVMSData { + int size; + union { + void *ptr; + struct POVMSNode *root; + }; + }; + struct POVMSNode { + struct POVMSNode *next; + unsigned int key; + struct POVMSData data; + }; + int POVMSObject_Set (POVMSObjectPtr object, POVMSAttributePtr attr, unsigned int key); + int POVMSAttr_Copy (POVMSAttributePtr sourceattr, POVMSAttributePtr destattr); + int POVMSUtil_GetType (POVMSObjectPtr object, unsigned int key, unsigned int *typevalue); + namespace pov_base { + enum { + kNoError = 0, kNoErr = kNoError, kParamErr = -1, kMemFullErr = -2, kOutOfMemoryErr = kMemFullErr, kInvalidDataSizeErr = -3, kCannotHandleDataErr = -4, kNullPointerErr = -5, kChecksumErr = -6, kParseErr = -7, kCannotOpenFileErr = -8, kInvalidDestAddrErr = -9, kCannotConnectErr = -10, kDisconnectedErr = -11, kHostDisconnectedErr = -12, kNetworkDataErr = -13, kNetworkConnectionErr = -14, kObjectAccessErr = -15, kVersionErr = -16, kFileDataErr = -17, kAuthorisationErr = -18, kDataTypeErr = -19, kTimeoutErr = -20, kInvalidContextErr = -21 }; + } + using namespace pov_base; + struct POVMSContextData { + }; + int POVMS_AssertFunction (int cond, const char *str, const char *filename, int line); + int POVMS_OpenContext(POVMSContext *contextrefptr) { + POVMSContextData *context = __null; + if(contextrefptr == __null) return kParamErr; + if(POVMS_AssertFunction(context != __null, "POVMS_Open_Context failed, out of memory", "povms.cpp", 283) == false) return kMemFullErr; + return kNoErr; + } + int POVMS_AssertFunction(int cond, const char *str, const char *filename, int line) { + if(cond == false) { + fprintf(stderr, "POVMS_ASSERT failed in %s line %d: %s\n", filename, (int)line, str); + } + } + int POVMSObject_Copy(POVMSObjectPtr sourceobject, POVMSObjectPtr destobject) { + POVMSNode *cur = __null; + POVMSAttribute attr; + unsigned int t1, t2; + int ret = kNoErr; + if(destobject == __null) return kParamErr; + if(POVMSUtil_GetType(sourceobject, kPOVMSObjectClassID, &t1) != kNoErr) return kObjectAccessErr; + if(POVMSUtil_GetType(sourceobject, kPOVMSObjectClassID, &t2) != kNoErr) return kObjectAccessErr; + if(t1 != t2) return kDataTypeErr; + for(cur = sourceobject->root; + cur != __null; + cur = cur->next) { + if(POVMS_AssertFunction(POVMSAttr_Copy(&(cur->data), &attr) == kNoErr, "POVMSObject_Merge failed, out of memory", "povms.cpp", 2084) == false) { + } + if(POVMS_AssertFunction(POVMSObject_Set(destobject, &attr, cur->key) == kNoErr, "POVMSObject_Merge failed, out of memory", "povms.cpp", 2090) == false) { + } + } + return ret; + } + int POVMSObject_Set(POVMSObjectPtr object, POVMSAttributePtr attr, unsigned int key) { + } + int POVMSAttrList_Copy(POVMSAttributeListPtr sourcelist, POVMSAttributeListPtr destlist) { + int cnt; + int err = kNoErr; + if(sourcelist == __null) return kParamErr; + if(destlist == __null) return kParamErr; + if(sourcelist == destlist) return kParamErr; + if(sourcelist->size < 0) return kParamErr; + if(sourcelist->size > 0) { + if(sourcelist->ptr != __null) { + if(POVMS_AssertFunction(destlist->ptr != __null, "POVMSAttrList_Copy failed, out of memory", "povms.cpp", 3020) == false) return -1; + } + for(cnt = 0; + cnt < sourcelist->size; + cnt++) { + } + } + return err; + } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 362211aa7b0..2d3958f2c04 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1741,7 +1741,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, most common reason for missing edges). */ gcc_assert (dest->needed || !dest->analyzed || dest->address_taken - || !id->src_node->analyzed); + || !id->src_node->analyzed + || !id->dst_node->analyzed); if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) cgraph_create_edge_including_clones (id->dst_node, dest, orig_stmt, stmt, bb->count, |