From baldrick at free.fr Mon Aug 20 01:19:55 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 08:19:55 +0200 Subject: [llvm-commits] [llvm-gcc-4.2] r41171 - in /llvm-gcc-4.2/trunk/gcc: except.c except.h llvm-convert.cpp llvm-internal.h In-Reply-To: <26CB5A9A-13F5-4DAA-A766-2ADBDFDC3E17@apple.com> References: <200708192017.l7JKHKjY030288@zion.cs.uiuc.edu> <26CB5A9A-13F5-4DAA-A766-2ADBDFDC3E17@apple.com> Message-ID: <200708200820.09302.baldrick@free.fr> Hi Chris, > > Exception handling rewrite - let gcc do the heavy > > lifting. This patch strips out the existing LLVM > > eh code, and replaces it with simpler code that > > exploits gcc's eh machinery. It requires running > > gcc's eh lowering pass (it was already being run > > in gcc-4.2). Not only is the new code simpler, > > it also handles more cases correctly (essentially > > all of the gcc eh tests) and results in better > > quality bytecode. In order to handle all of the > > gcc tests correctly, some small tweaks need to be > > made to the way LLVM handles the "nounwind" > > attribute. I plan to take care of this later. > > Excellent! Can you elaborate on what the nounwind change is? I want to mark some function calls nounwind - this will be used for calls in so-called no-throw regions and for calls to nothrow functions (in the later case, the function itself can be marked nounwind). Next, if a call is marked nounwind, then the call should not get an entry in the dwarf exception tables (this causes the C++ personality function, i.e. the runtime, to terminate the program if the call throws an exception). Then some changes need to be made to the optimizers: if a nounwind call is inlined, then the nounwind attribute needs to be propagated to any calls in the inlined function; also, if an indirect nounwind call is resolved to a direct call to a non nounwind function then the nounwind marking should not be lost etc. Probably some other attributes could do with this kind of treatment too. That said, this way of implementing nothrow may cause trouble later when we try to support mixed language operation: suppose that inlining causes an Ada function to perform a C++ nounwind call. The Ada personality won't terminate the program if that routine does throw an exception, it will just keep on unwinding. The essential problem is that nounwind does not require specifying the (C++) personality, it is not an invoke. [gcc also does not use a personality for a function containing nothrow calls, unless some other eh constructs are present]. Another implementation of nothrow would be to turn nothrow calls into invokes with an empty filter and an explicit terminate call. But that would fatten the bytecode plus it would cause a bunch of extra dwarf stuff to be output, all to handle an obscure case. My plan is to use nounwind for the moment, and worry about this problem when we start work on handling multiple personality functions. > Welcome back Duncan, I'm still on holiday :) Ciao, Duncan. From rafael.espindola at gmail.com Mon Aug 20 10:18:24 2007 From: rafael.espindola at gmail.com (Rafael Espindola) Date: Mon, 20 Aug 2007 15:18:24 -0000 Subject: [llvm-commits] [llvm] r41179 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/X86/X86ISelLowering.cpp Message-ID: <200708201518.l7KFIP0f012597@zion.cs.uiuc.edu> Author: rafael Date: Mon Aug 20 10:18:24 2007 New Revision: 41179 URL: http://llvm.org/viewvc/llvm-project?rev=41179&view=rev Log: Partial implementation of calling functions with byval arguments: *) The needed information is propagated to the DAG *) The X86-64 backend detects it and aborts Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=41179&r1=41178&r2=41179&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Mon Aug 20 10:18:24 2007 @@ -841,9 +841,10 @@ bool isInReg; bool isSRet; bool isNest; + bool isByVal; ArgListEntry() : isSExt(false), isZExt(false), isInReg(false), - isSRet(false), isNest(false) { }; + isSRet(false), isNest(false), isByVal(false) { }; }; typedef std::vector ArgListTy; virtual std::pair Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=41179&r1=41178&r2=41179&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Aug 20 10:18:24 2007 @@ -2905,6 +2905,7 @@ Entry.isInReg = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::InReg); Entry.isSRet = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::StructRet); Entry.isNest = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::Nest); + Entry.isByVal = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ByVal); Args.push_back(Entry); } @@ -3967,6 +3968,15 @@ Flags |= ISD::ParamFlags::InReg; if (Args[i].isSRet) Flags |= ISD::ParamFlags::StructReturn; + if (Args[i].isByVal) { + Flags |= ISD::ParamFlags::ByVal; + const PointerType *Ty = cast(Args[i].Ty); + const StructType *STy = cast(Ty->getElementType()); + unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy)); + unsigned StructSize = getTargetData()->getTypeSize(STy); + Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs); + Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs); + } if (Args[i].isNest) Flags |= ISD::ParamFlags::Nest; Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs; Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=41179&r1=41178&r2=41179&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Aug 20 10:18:24 2007 @@ -1378,7 +1378,27 @@ StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy()); SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy()); PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff); - MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); + + SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo()); + unsigned Flags = cast(FlagsOp)->getValue(); + if (Flags & ISD::ParamFlags::ByVal) { + unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >> + ISD::ParamFlags::ByValAlignOffs); + unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >> + ISD::ParamFlags::ByValSizeOffs; + + SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); + SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); + + assert(0 && "Not Implemented"); + + SDOperand Copy = DAG.getNode(ISD::MEMCPY, MVT::Other, Chain, PtrOff, + Arg, SizeNode, AlignNode); + MemOpChains.push_back(Copy); + } + else { + MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); + } } } From baldrick at free.fr Mon Aug 20 12:02:01 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 17:02:01 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41182 - /llvm-gcc-4.2/trunk/gcc/passes.c Message-ID: <200708201702.l7KH22No017793@zion.cs.uiuc.edu> Author: baldrick Date: Mon Aug 20 12:02:01 2007 New Revision: 41182 URL: http://llvm.org/viewvc/llvm-project?rev=41182&view=rev Log: The gcc vector lowering pass should only be turned off if LLVM is enabled. Modified: llvm-gcc-4.2/trunk/gcc/passes.c Modified: llvm-gcc-4.2/trunk/gcc/passes.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/passes.c?rev=41182&r1=41181&r2=41182&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/passes.c (original) +++ llvm-gcc-4.2/trunk/gcc/passes.c Mon Aug 20 12:02:01 2007 @@ -496,8 +496,11 @@ NEXT_PASS (pass_lower_eh); NEXT_PASS (pass_build_cfg); NEXT_PASS (pass_lower_complex_O0); - /* LLVM LOCAL */ - /* NEXT_PASS (pass_lower_vector); */ + /* LLVM LOCAL begin */ +#ifndef ENABLE_LLVM + NEXT_PASS (pass_lower_vector); +#endif + /* LLVM LOCAL end */ NEXT_PASS (pass_warn_function_return); NEXT_PASS (pass_early_tree_profile); *p = NULL; From baldrick at free.fr Mon Aug 20 12:04:56 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 17:04:56 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41183 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200708201704.l7KH4uOn017872@zion.cs.uiuc.edu> Author: baldrick Date: Mon Aug 20 12:04:56 2007 New Revision: 41183 URL: http://llvm.org/viewvc/llvm-project?rev=41183&view=rev Log: Rather than calling disband_implicit_edges (which does a bunch of things we don't need), handle fall-through edges directly. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41183&r1=41182&r2=41183&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Aug 20 12:04:56 2007 @@ -382,6 +382,22 @@ TheTreeToLLVM = 0; } +/// getLabelDeclBlock - Lazily get and create a basic block for the specified +/// label. +static BasicBlock *getLabelDeclBlock(tree LabelDecl) { + assert(TREE_CODE(LabelDecl) == LABEL_DECL && "Isn't a label!?"); + if (DECL_LLVM_SET_P(LabelDecl)) + return cast(DECL_LLVM(LabelDecl)); + + const char *Name = "bb"; + if (DECL_NAME(LabelDecl)) + Name = IDENTIFIER_POINTER(DECL_NAME(LabelDecl)); + + BasicBlock *NewBB = new BasicBlock(Name); + SET_DECL_LLVM(LabelDecl, NewBB); + return NewBB; +} + namespace { /// FunctionPrologArgumentConversion - This helper class is driven by the ABI /// definition for this target to figure out how to retrieve arguments from @@ -757,15 +773,23 @@ // Set up parameters and prepare for return, for the function. StartFunctionBody(); - // Drop all fallthru edges, make explicit jumps - disband_implicit_edges(); - // Emit the body of the function iterating over all BBs basic_block bb; - FOR_EACH_BB (bb) + edge e; + edge_iterator ei; + FOR_EACH_BB (bb) { for (block_stmt_iterator bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) EmitStatement(bsi_stmt (bsi)); + + FOR_EACH_EDGE (e, ei, bb->succs) + if (e->flags & EDGE_FALLTHRU) + break; + if (e && e->dest != bb->next_bb) { + Builder.CreateBr(getLabelDeclBlock(tree_block_label (e->dest))); + EmitBlock(new BasicBlock("")); + } + } // Wrap things up. return FinishFunctionBody(); @@ -1617,22 +1641,6 @@ // ... Control Flow ... //===----------------------------------------------------------------------===// -/// getLabelDeclBlock - Lazily get and create a basic block for the specified -/// label. -static BasicBlock *getLabelDeclBlock(tree LabelDecl) { - assert(TREE_CODE(LabelDecl) == LABEL_DECL && "Isn't a label!?"); - if (DECL_LLVM_SET_P(LabelDecl)) - return cast(DECL_LLVM(LabelDecl)); - - const char *Name = "bb"; - if (DECL_NAME(LabelDecl)) - Name = IDENTIFIER_POINTER(DECL_NAME(LabelDecl)); - - BasicBlock *NewBB = new BasicBlock(Name); - SET_DECL_LLVM(LabelDecl, NewBB); - return NewBB; -} - /// EmitLABEL_EXPR - Emit the basic block corresponding to the specified label. /// Value *TreeToLLVM::EmitLABEL_EXPR(tree exp) { From baldrick at free.fr Mon Aug 20 12:06:52 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 17:06:52 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41184 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200708201706.l7KH6qvB017931@zion.cs.uiuc.edu> Author: baldrick Date: Mon Aug 20 12:06:52 2007 New Revision: 41184 URL: http://llvm.org/viewvc/llvm-project?rev=41184&view=rev Log: In cfg gimple, both branches of a COND_EXPR are guaranteed to be gotos. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41184&r1=41183&r2=41184&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Aug 20 12:06:52 2007 @@ -1698,82 +1698,16 @@ if (Cond->getType() != Type::Int1Ty) Cond = Builder.CreateICmpNE(Cond, Constant::getNullValue(Cond->getType()), "toBool"); + tree Then = COND_EXPR_THEN(exp); tree Else = COND_EXPR_ELSE(exp); + assert(TREE_CODE(Then) == GOTO_EXPR && TREE_CODE(Else) == GOTO_EXPR + && "Not a gimple if?"); - // One extremely common pattern produced by the loop lowering code are - // COND_EXPRS that look like: - // - // if (cond) { goto ; } else { goto ; } - // - // The generic code handles this below, but there is no reason to create a - // cond branch to two blocks which just contain branches themselves. - if (TREE_CODE(Then) == STATEMENT_LIST && TREE_CODE(Else) == STATEMENT_LIST) { - tree_stmt_iterator ThenI = tsi_start(Then), ElseI = tsi_start(Else); - if (!tsi_end_p(ThenI) && !tsi_end_p(ElseI)) { // {} isn't empty. - tree ThenStmt = tsi_stmt(ThenI), ElseStmt = tsi_stmt(ElseI); - tsi_next(&ThenI); - tsi_next(&ElseI); - - if (TREE_CODE(ThenStmt) == GOTO_EXPR && // Found two uncond gotos. - TREE_CODE(ElseStmt) == GOTO_EXPR && - tsi_end_p(ThenI) && tsi_end_p(ElseI) && // Nothing after them. - TREE_CODE(TREE_OPERAND(ThenStmt, 0)) == LABEL_DECL &&// Not goto *p. - TREE_CODE(TREE_OPERAND(ElseStmt, 0)) == LABEL_DECL) { - BasicBlock *ThenDest = getLabelDeclBlock(TREE_OPERAND(ThenStmt, 0)); - BasicBlock *ElseDest = getLabelDeclBlock(TREE_OPERAND(ElseStmt, 0)); - - // Okay, we have success. Output the conditional branch. - Builder.CreateCondBr(Cond, ThenDest, ElseDest); - // Emit a "fallthrough" block, which is almost certainly dead. - EmitBlock(new BasicBlock("")); - return 0; - } - } - } - - BasicBlock *TrueBlock = new BasicBlock("cond_true"); - BasicBlock *FalseBlock; - BasicBlock *ContBlock = new BasicBlock("cond_next"); - - // Another extremely common case we want to handle are if/then blocks with - // no else. The gimplifier turns these into: - // - // if (cond) { goto ; } else { } - // - // Recognize when the else is an empty STATEMENT_LIST, and don't emit the - // else if so. - // - bool HasEmptyElse = - TREE_CODE(Else) == STATEMENT_LIST && tsi_end_p(tsi_start(Else)); - - if (HasEmptyElse) - FalseBlock = ContBlock; - else - FalseBlock = new BasicBlock("cond_false"); - - // Emit the branch based on the condition. - Builder.CreateCondBr(Cond, TrueBlock, FalseBlock); - - // Emit the true code. - EmitBlock(TrueBlock); - - Emit(Then, 0); - - // If this is an if/then/else cond-expr, emit the else part, otherwise, just - // fall through to the ContBlock. - if (!HasEmptyElse) { - if (Builder.GetInsertBlock()->getTerminator() == 0 && - (!Builder.GetInsertBlock()->getName().empty() || - !Builder.GetInsertBlock()->use_empty())) - Builder.CreateBr(ContBlock); // Branch to continue block. - - EmitBlock(FalseBlock); - - Emit(Else, 0); - } - - EmitBlock(ContBlock); + BasicBlock *ThenDest = getLabelDeclBlock(TREE_OPERAND(Then, 0)); + BasicBlock *ElseDest = getLabelDeclBlock(TREE_OPERAND(Else, 0)); + Builder.CreateCondBr(Cond, ThenDest, ElseDest); + EmitBlock(new BasicBlock("")); return 0; } From baldrick at free.fr Mon Aug 20 12:08:47 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 17:08:47 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41185 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h Message-ID: <200708201708.l7KH8l2L017986@zion.cs.uiuc.edu> Author: baldrick Date: Mon Aug 20 12:08:47 2007 New Revision: 41185 URL: http://llvm.org/viewvc/llvm-project?rev=41185&view=rev Log: In cfg gimple, BIND_EXPR and STATEMENT_LIST are not possible: they have already been lowered by gcc. So all this code is dead. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-internal.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41185&r1=41184&r2=41185&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Aug 20 12:08:47 2007 @@ -779,8 +779,18 @@ edge_iterator ei; FOR_EACH_BB (bb) { for (block_stmt_iterator bsi = bsi_start (bb); !bsi_end_p (bsi); - bsi_next (&bsi)) - EmitStatement(bsi_stmt (bsi)); + bsi_next (&bsi)) { + tree stmt = bsi_stmt (bsi); + Value *DestLoc = 0; + + // If this stmt returns an aggregate value (e.g. a call whose result is + // ignored), create a temporary to receive the value. Note that we don't + // do this for MODIFY_EXPRs as an efficiency hack. + if (isAggregateTreeType(TREE_TYPE(stmt)) && TREE_CODE(stmt) != MODIFY_EXPR) + DestLoc = CreateTemporary(ConvertType(TREE_TYPE(stmt))); + + Emit(stmt, DestLoc); + } FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALLTHRU) @@ -808,10 +818,6 @@ TheDebugInfo->setLocationFile(EXPR_FILENAME(exp)); TheDebugInfo->setLocationLine(EXPR_LINENO(exp)); } - - // These node create an artificial jump to end of block. - if (TREE_CODE(exp) != BIND_EXPR && TREE_CODE(exp) != STATEMENT_LIST) - TheDebugInfo->EmitStopPoint(Fn, Builder.GetInsertBlock()); } switch (TREE_CODE(exp)) { @@ -821,10 +827,6 @@ debug_tree(exp); abort(); - // Basic lists and binding scopes - case BIND_EXPR: Result = EmitBIND_EXPR(exp, DestLoc); break; - case STATEMENT_LIST: Result = EmitSTATEMENT_LIST(exp, DestLoc); break; - // Control flow case LABEL_EXPR: Result = EmitLABEL_EXPR(exp); break; case GOTO_EXPR: Result = EmitGOTO_EXPR(exp); break; @@ -1534,71 +1536,6 @@ } } -Value *TreeToLLVM::EmitBIND_EXPR(tree exp, Value *DestLoc) { - // Start region only if not top level. - if (TheDebugInfo && DECL_SAVED_TREE(FnDecl) != exp) - TheDebugInfo->EmitRegionStart(Fn, Builder.GetInsertBlock()); - - // Mark the corresponding BLOCK for output in its proper place. - if (BIND_EXPR_BLOCK(exp) != 0 && !TREE_USED(BIND_EXPR_BLOCK(exp))) - TREE_USED(BIND_EXPR_BLOCK(exp)) = 1; - //lang_hooks.decls.insert_block(BIND_EXPR_BLOCK(exp)); - - // If VARS have not yet been expanded, expand them now. - tree Var = BIND_EXPR_VARS(exp); - for (; Var; Var = TREE_CHAIN(Var)) { - if (TREE_STATIC(Var)) { - // If this is an inlined copy of a static local variable, look up the - // original. - tree RealVar = DECL_ORIGIN(Var); - - // If we haven't already emitted the var, do so now. - if (!TREE_ASM_WRITTEN(RealVar) && !lang_hooks.expand_decl(RealVar) && - TREE_CODE (Var) == VAR_DECL) - rest_of_decl_compilation(RealVar, 0, 0); - continue; - } - - // Otherwise, if this is an automatic variable that hasn't been emitted, do - // so now. - if (!DECL_LLVM_SET_P(Var)) - EmitAutomaticVariableDecl(Var); - } - - // Finally, emit the body of the bind expression. - Value *Result = Emit(BIND_EXPR_BODY(exp), DestLoc); - - TREE_USED(exp) = 1; - - // End region only if not top level. - if (TheDebugInfo && DECL_SAVED_TREE(FnDecl) != exp) - TheDebugInfo->EmitRegionEnd(Fn, Builder.GetInsertBlock()); - - return Result; -} - -void TreeToLLVM::EmitStatement(tree stmt) { - Value *DestLoc = 0; - - // If this stmt returns an aggregate value (e.g. a call whose result is - // ignored), create a temporary to receive the value. Note that we don't - // do this for MODIFY_EXPRs as an efficiency hack. - if (isAggregateTreeType(TREE_TYPE(stmt)) && TREE_CODE(stmt) != MODIFY_EXPR) - DestLoc = CreateTemporary(ConvertType(TREE_TYPE(stmt))); - - Emit(stmt, DestLoc); -} - -Value *TreeToLLVM::EmitSTATEMENT_LIST(tree exp, Value *DestLoc) { - assert(DestLoc == 0 && "Does not return a value!"); - - // Convert each statement. - for (tree_stmt_iterator I = tsi_start(exp); !tsi_end_p(I); tsi_next(&I)) - EmitStatement(tsi_stmt(I)); - - return 0; -} - //===----------------------------------------------------------------------===// // ... Address Of Labels Extension Support ... //===----------------------------------------------------------------------===// Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=41185&r1=41184&r2=41185&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Mon Aug 20 12:08:47 2007 @@ -387,9 +387,6 @@ /// DestLoc. Value *Emit(tree_node *exp, Value *DestLoc); - /// EmitStatement - Convert the specified statement to LLVM code. - void EmitStatement(tree_node *stmt); - /// EmitBlock - Add the specified basic block to the end of the function. If /// the previous block falls through into it, add an explicit branch. void EmitBlock(BasicBlock *BB); @@ -449,10 +446,6 @@ // Emit* - These are delegates from Emit, and have the same parameter // characteristics. - // Basic lists and binding scopes. - Value *EmitBIND_EXPR(tree_node *exp, Value *DestLoc); - Value *EmitSTATEMENT_LIST(tree_node *exp, Value *DestLoc); - // Control flow. Value *EmitLABEL_EXPR(tree_node *exp); Value *EmitGOTO_EXPR(tree_node *exp); From baldrick at free.fr Mon Aug 20 12:10:50 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 17:10:50 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41186 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h Message-ID: <200708201710.l7KHAona018086@zion.cs.uiuc.edu> Author: baldrick Date: Mon Aug 20 12:10:50 2007 New Revision: 41186 URL: http://llvm.org/viewvc/llvm-project?rev=41186&view=rev Log: "FIXME: When merged with mainline, remove this code." That presumably means now. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-internal.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41186&r1=41185&r2=41186&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Aug 20 12:10:50 2007 @@ -962,10 +962,7 @@ // Constant Expressions case INTEGER_CST: - if (!DestLoc) - Result = TreeConstantToLLVM::ConvertINTEGER_CST(exp); - else - EmitINTEGER_CST_Aggregate(exp, DestLoc); + Result = TreeConstantToLLVM::ConvertINTEGER_CST(exp); break; case REAL_CST: Result = TreeConstantToLLVM::ConvertREAL_CST(exp); @@ -1994,23 +1991,6 @@ // ... Expressions ... //===----------------------------------------------------------------------===// -/// EmitINTEGER_CST_Aggregate - The C++ front-end abuses INTEGER_CST nodes to -/// represent empty classes. For now we check that this is the case we handle, -/// then zero out DestLoc. -/// -/// FIXME: When merged with mainline, remove this code. The C++ front-end has -/// been fixed. -/// -void TreeToLLVM::EmitINTEGER_CST_Aggregate(tree exp, Value *DestLoc) { - tree type = TREE_TYPE(exp); -#ifndef NDEBUG - assert(TREE_CODE(type) == RECORD_TYPE && "Not an empty class!"); - for (tree F = TYPE_FIELDS(type); F; F = TREE_CHAIN(F)) - assert(TREE_CODE(F) != FIELD_DECL && "Not an empty struct/class!"); -#endif - EmitAggregateZero(DestLoc, type); -} - /// EmitLoadOfLValue - When an l-value expression is used in a context that /// requires an r-value, this method emits the lvalue computation, then loads /// the result. Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=41186&r1=41185&r2=41186&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Mon Aug 20 12:10:50 2007 @@ -454,7 +454,6 @@ Value *EmitSWITCH_EXPR(tree_node *exp); // Expressions. - void EmitINTEGER_CST_Aggregate(tree_node *exp, Value *DestLoc); Value *EmitLoadOfLValue(tree_node *exp, Value *DestLoc); Value *EmitOBJ_TYPE_REF(tree_node *exp, Value *DestLoc); Value *EmitADDR_EXPR(tree_node *exp); From baldrick at free.fr Mon Aug 20 12:14:02 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 17:14:02 -0000 Subject: [llvm-commits] [llvm] r41187 - /llvm/trunk/test/C++Frontend/2007-05-23-TryFinally.cpp Message-ID: <200708201714.l7KHE2p7018419@zion.cs.uiuc.edu> Author: baldrick Date: Mon Aug 20 12:14:02 2007 New Revision: 41187 URL: http://llvm.org/viewvc/llvm-project?rev=41187&view=rev Log: Fix this test for gcc-4.2. Modified: llvm/trunk/test/C++Frontend/2007-05-23-TryFinally.cpp Modified: llvm/trunk/test/C++Frontend/2007-05-23-TryFinally.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/C%2B%2BFrontend/2007-05-23-TryFinally.cpp?rev=41187&r1=41186&r2=41187&view=diff ============================================================================== --- llvm/trunk/test/C++Frontend/2007-05-23-TryFinally.cpp (original) +++ llvm/trunk/test/C++Frontend/2007-05-23-TryFinally.cpp Mon Aug 20 12:14:02 2007 @@ -1,5 +1,5 @@ // RUN: %llvmgxx %s -S -emit-llvm -O2 -o - | ignore grep _Unwind_Resume | \ -// RUN: wc -l | grep {\[02\]} +// RUN: wc -l | grep {\[23\]} struct One { }; struct Two { }; From raulherbster at gmail.com Mon Aug 20 14:15:19 2007 From: raulherbster at gmail.com (Raul Fernandes Herbster) Date: Mon, 20 Aug 2007 16:15:19 -0300 Subject: [llvm-commits] [PATCH] JIT support for ARM In-Reply-To: <6fbb4ff20708171728u52190d10p7f5dc87268d5a46e@mail.gmail.com> References: <6fbb4ff20708161407u49bd1833k8e6d147371d9515@mail.gmail.com> <77A7A5D7-BDEF-4D8E-AA73-B7E488F72180@apple.com> <6fbb4ff20708171728u52190d10p7f5dc87268d5a46e@mail.gmail.com> Message-ID: <6fbb4ff20708201215r36e562ealfa0d7bc404aa382e@mail.gmail.com> Evan, thanks a lot for your comments. I fixed the code (as discussed previously). Cheers. -- Raul Fernandes Herbster Embedded and Pervasive Computing Laboratory - embedded.dee.ufcg.edu.br Electrical Engineering Department - DEE - www.dee.ufcg.edu.br Electrical Engineering and Informatics Center - CEEI Federal University of Campina Grande - UFCG - www.ufcg.edu.br Caixa Postal 10105 58109-970 Campina Grande - PB - Brasil -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070820/2f7fe26c/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: patch Type: application/octet-stream Size: 34400 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070820/2f7fe26c/attachment.obj From djg at cray.com Mon Aug 20 14:23:35 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 20 Aug 2007 19:23:35 -0000 Subject: [llvm-commits] [llvm] r41189 - /llvm/trunk/lib/VMCore/Function.cpp Message-ID: <200708201923.l7KJNZP6025044@zion.cs.uiuc.edu> Author: djg Date: Mon Aug 20 14:23:34 2007 New Revision: 41189 URL: http://llvm.org/viewvc/llvm-project?rev=41189&view=rev Log: When Intrinsic::getName is constructing names for overloaded intrinsics, use the ValueType name instead of the llvm type name, to match what the verifier expects. For integers these are the same, but for floating-point values the intrinsics use f32/f64 instead of float/double. Modified: llvm/trunk/lib/VMCore/Function.cpp Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=41189&r1=41188&r2=41189&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Mon Aug 20 14:23:34 2007 @@ -15,6 +15,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/ParameterAttributes.h" #include "llvm/IntrinsicInst.h" +#include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "SymbolTableListTraitsImpl.h" @@ -287,7 +288,7 @@ std::string Result(Table[id]); for (unsigned i = 0; i < numTys; ++i) if (Tys[i]) - Result += "." + Tys[i]->getDescription(); + Result += "." + MVT::getValueTypeString(MVT::getValueType(Tys[i])); return Result; } From djg at cray.com Mon Aug 20 14:25:59 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 20 Aug 2007 19:25:59 -0000 Subject: [llvm-commits] [llvm] r41190 - in /llvm/trunk: include/llvm/Type.h lib/VMCore/Type.cpp Message-ID: <200708201925.l7KJPx51025263@zion.cs.uiuc.edu> Author: djg Date: Mon Aug 20 14:25:59 2007 New Revision: 41190 URL: http://llvm.org/viewvc/llvm-project?rev=41190&view=rev Log: Add Type::isIntOrIntVector, like Type::isFPOrFPVector. Modified: llvm/trunk/include/llvm/Type.h llvm/trunk/lib/VMCore/Type.cpp Modified: llvm/trunk/include/llvm/Type.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Type.h?rev=41190&r1=41189&r2=41190&view=diff ============================================================================== --- llvm/trunk/include/llvm/Type.h (original) +++ llvm/trunk/include/llvm/Type.h Mon Aug 20 14:25:59 2007 @@ -180,6 +180,11 @@ /// bool isInteger() const { return ID == IntegerTyID; } + /// isIntOrIntVector - Return true if this is an integer type or a vector of + /// integer types. + /// + bool isIntOrIntVector() const; + /// isFloatingPoint - Return true if this is one of the two floating point /// types bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID || Modified: llvm/trunk/lib/VMCore/Type.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Type.cpp?rev=41190&r1=41189&r2=41190&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Type.cpp (original) +++ llvm/trunk/lib/VMCore/Type.cpp Mon Aug 20 14:25:59 2007 @@ -126,6 +126,17 @@ return this; } +/// isIntOrIntVector - Return true if this is an integer type or a vector of +/// integer types. +/// +bool Type::isIntOrIntVector() const { + if (isInteger()) + return true; + if (ID != Type::VectorTyID) return false; + + return cast(this)->getElementType()->isInteger(); +} + /// isFPOrFPVector - Return true if this is a FP type or a vector of FP types. /// bool Type::isFPOrFPVector() const { From djg at cray.com Mon Aug 20 14:28:40 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 20 Aug 2007 19:28:40 -0000 Subject: [llvm-commits] [llvm] r41191 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Message-ID: <200708201928.l7KJSea9025343@zion.cs.uiuc.edu> Author: djg Date: Mon Aug 20 14:28:38 2007 New Revision: 41191 URL: http://llvm.org/viewvc/llvm-project?rev=41191&view=rev Log: Minor cleanups to reduce some spurious differences between different scheduler implementations. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp?rev=41191&r1=41190&r2=41191&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp Mon Aug 20 14:28:38 2007 @@ -45,7 +45,6 @@ /// ScheduleDAGRRList - The actual register reduction list scheduler /// implementation. This supports both top-down and bottom-up scheduling. /// - class VISIBILITY_HIDDEN ScheduleDAGRRList : public ScheduleDAG { private: /// isBottomUp - This is true if the scheduling problem is bottom-up, false if @@ -95,7 +94,7 @@ CalculateHeights(); AvailableQueue->initNodes(SUnitMap, SUnits); - + // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate. if (isBottomUp) ListScheduleBottomUp(); @@ -103,7 +102,7 @@ ListScheduleTopDown(); AvailableQueue->releaseState(); - + CommuteNodesToReducePressure(); DOUT << "*** Final schedule ***\n"; @@ -169,7 +168,7 @@ //===----------------------------------------------------------------------===// /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to -/// the Available queue is the count reaches zero. Also update its cycle bound. +/// the AvailableQueue if the count reaches zero. Also update its cycle bound. void ScheduleDAGRRList::ReleasePred(SUnit *PredSU, bool isChain, unsigned CurCycle) { // FIXME: the distance between two nodes is not always == the predecessor's @@ -233,7 +232,7 @@ AvailableQueue->push(SUnitMap[DAG.getRoot().Val]); // While Available queue is not empty, grab the node with the highest - // priority. If it is not ready put it back. Schedule the node. + // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; while (!AvailableQueue->empty()) { SUnit *CurNode = AvailableQueue->pop(); @@ -282,7 +281,7 @@ //===----------------------------------------------------------------------===// /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to -/// the PendingQueue if the count reaches zero. +/// the AvailableQueue if the count reaches zero. Also update its cycle bound. void ScheduleDAGRRList::ReleaseSucc(SUnit *SuccSU, bool isChain, unsigned CurCycle) { // FIXME: the distance between two nodes is not always == the predecessor's @@ -330,6 +329,8 @@ SU->isScheduled = true; } +/// ListScheduleTopDown - The main loop of list scheduling for top-down +/// schedulers. void ScheduleDAGRRList::ListScheduleTopDown() { unsigned CurCycle = 0; SUnit *Entry = SUnitMap[DAG.getEntryNode().Val]; @@ -348,7 +349,7 @@ CurCycle++; // While Available queue is not empty, grab the node with the highest - // priority. If it is not ready put it back. Schedule the node. + // priority. If it is not ready put it back. Schedule the node. std::vector NotReady; while (!AvailableQueue->empty()) { SUnit *CurNode = AvailableQueue->pop(); @@ -474,7 +475,7 @@ const TargetInstrInfo *TII; public: - BURegReductionPriorityQueue(const TargetInstrInfo *tii) + explicit BURegReductionPriorityQueue(const TargetInstrInfo *tii) : TII(tii) {} void initNodes(DenseMap &sumap, @@ -539,7 +540,8 @@ template - class TDRegReductionPriorityQueue : public RegReductionPriorityQueue { + class VISIBILITY_HIDDEN TDRegReductionPriorityQueue + : public RegReductionPriorityQueue { // SUnitMap SDNode to SUnit mapping (n -> 1). DenseMap *SUnitMap; From greened at obbligato.org Mon Aug 20 14:54:03 2007 From: greened at obbligato.org (David Greene) Date: Mon, 20 Aug 2007 19:54:03 -0000 Subject: [llvm-commits] [llvm] r41192 - /llvm/trunk/include/llvm/Support/PassNameParser.h Message-ID: <200708201954.l7KJs4sl026117@zion.cs.uiuc.edu> Author: greened Date: Mon Aug 20 14:54:01 2007 New Revision: 41192 URL: http://llvm.org/viewvc/llvm-project?rev=41192&view=rev Log: Add FilteredPassNameParser along with PassArgFilter to filter passes based on their Arg members. Modified: llvm/trunk/include/llvm/Support/PassNameParser.h Modified: llvm/trunk/include/llvm/Support/PassNameParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PassNameParser.h?rev=41192&r1=41191&r2=41192&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PassNameParser.h (original) +++ llvm/trunk/include/llvm/Support/PassNameParser.h Mon Aug 20 14:54:01 2007 @@ -24,9 +24,9 @@ #define LLVM_SUPPORT_PASS_NAME_PARSER_H #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" #include "llvm/Pass.h" #include +#include namespace llvm { @@ -89,6 +89,44 @@ } }; -} // End llvm namespace +//===----------------------------------------------------------------------===// +// FilteredPassNameParser class - Make use of the pass registration +// mechanism to automatically add a command line argument to opt for +// each pass that satisfies a filter criteria. Filter should return +// true for passes to be registered as command-line options. +// +template +class FilteredPassNameParser : public PassNameParser { +private: + Filter filter; +public: + bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); } +}; + +//===----------------------------------------------------------------------===// +// PassArgFilter - A filter for use with PassNameFilterParser that only +// accepts a Pass whose Arg matches certain strings. +// +// Use like this: +// +// extern const char AllowedPassArgs[] = "-anders_aa -dse"; +// +// static cl::list< +// const PassInfo*, +// bool, +// FilteredPassNameParser > > +// PassList(cl::desc("LLVM optimizations available:")); +// +// Only the -anders_aa and -dse options will be available to the user. +// +template +class PassArgFilter { +public: + bool operator()(const PassInfo &P) const { + return(std::strstr(Args, P.getPassArgument())); + } +}; + +} // End llvm namespace #endif From baldrick at free.fr Mon Aug 20 15:14:34 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 20:14:34 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41193 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200708202014.l7KKEYcD027188@zion.cs.uiuc.edu> Author: baldrick Date: Mon Aug 20 15:14:33 2007 New Revision: 41193 URL: http://llvm.org/viewvc/llvm-project?rev=41193&view=rev Log: Restore wrongly removed call. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41193&r1=41192&r2=41193&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Aug 20 15:14:33 2007 @@ -818,6 +818,8 @@ TheDebugInfo->setLocationFile(EXPR_FILENAME(exp)); TheDebugInfo->setLocationLine(EXPR_LINENO(exp)); } + + TheDebugInfo->EmitStopPoint(Fn, Builder.GetInsertBlock()); } switch (TREE_CODE(exp)) { From dpatel at apple.com Mon Aug 20 15:24:16 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 20 Aug 2007 20:24:16 -0000 Subject: [llvm-commits] [llvm] r41194 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/Crash-2007-08-17.ll test/Transforms/LoopIndexSplit/Crash2-2007-08-17.ll Message-ID: <200708202024.l7KKOGGS027534@zion.cs.uiuc.edu> Author: dpatel Date: Mon Aug 20 15:24:15 2007 New Revision: 41194 URL: http://llvm.org/viewvc/llvm-project?rev=41194&view=rev Log: Do not split loops rejected by processOneIterationLoop(). Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-08-17.ll llvm/trunk/test/Transforms/LoopIndexSplit/Crash2-2007-08-17.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41194&r1=41193&r2=41194&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Mon Aug 20 15:24:15 2007 @@ -178,7 +178,7 @@ // First see if it is possible to eliminate loop itself or not. for (SmallVector::iterator SI = SplitData.begin(), - E = SplitData.end(); SI != E; ++SI) { + E = SplitData.end(); SI != E;) { SplitInfo &SD = *SI; if (SD.SplitCondition->getPredicate() == ICmpInst::ICMP_EQ) { Changed = processOneIterationLoop(SD); @@ -186,8 +186,13 @@ ++NumIndexSplit; // If is loop is eliminated then nothing else to do here. return Changed; + } else { + SmallVector::iterator Delete_SI = SI; + ++SI; + SplitData.erase(Delete_SI); } - } + } else + ++SI; } unsigned MaxCost = 99; @@ -198,8 +203,8 @@ SplitInfo SD = *SI; // ICM_EQs are already handled above. - if (SD.SplitCondition->getPredicate() == ICmpInst::ICMP_EQ) - continue; + assert (SD.SplitCondition->getPredicate() != ICmpInst::ICMP_EQ && + "Unexpected split condition predicate"); unsigned Cost = findSplitCost(L, SD); if (Cost < MaxCost) @@ -207,7 +212,8 @@ } // Split most profitiable condition. - Changed = splitLoop(SplitData[MostProfitableSDIndex]); + if (!SplitData.empty()) + Changed = splitLoop(SplitData[MostProfitableSDIndex]); if (Changed) ++NumIndexSplit; Modified: llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-08-17.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-08-17.ll?rev=41194&r1=41193&r2=41194&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-08-17.ll (original) +++ llvm/trunk/test/Transforms/LoopIndexSplit/Crash-2007-08-17.ll Mon Aug 20 15:24:15 2007 @@ -1,5 +1,4 @@ -; RUN: llvm-as < %s | opt -loop-index-split -disable-output -stats |& \ -; RUN: grep "loop-index-split" | count 1 +; RUN: llvm-as < %s | opt -loop-index-split -disable-output %struct._edit_script = type { %struct._edit_script*, i32, i8 } Modified: llvm/trunk/test/Transforms/LoopIndexSplit/Crash2-2007-08-17.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/Crash2-2007-08-17.ll?rev=41194&r1=41193&r2=41194&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/Crash2-2007-08-17.ll (original) +++ llvm/trunk/test/Transforms/LoopIndexSplit/Crash2-2007-08-17.ll Mon Aug 20 15:24:15 2007 @@ -1,5 +1,4 @@ -; RUN: llvm-as < %s | opt -loop-index-split -disable-output -stats |& \ -; RUN: grep "loop-index-split" | count 1 +; RUN: llvm-as < %s | opt -loop-index-split -disable-output %struct._edit_script = type { %struct._edit_script*, i32, i8 } From dpatel at apple.com Mon Aug 20 15:49:01 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 20 Aug 2007 20:49:01 -0000 Subject: [llvm-commits] [llvm] r41195 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708202049.l7KKn233028685@zion.cs.uiuc.edu> Author: dpatel Date: Mon Aug 20 15:49:01 2007 New Revision: 41195 URL: http://llvm.org/viewvc/llvm-project?rev=41195&view=rev Log: Replace indunction variable with split value in loop body. This fixes art miscompile. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41195&r1=41194&r2=41195&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Mon Aug 20 15:49:01 2007 @@ -418,7 +418,11 @@ // Update CFG. - // As a first step to break this loop, remove Latch to Header edge. + // Replace index variable with split value in loop body. Loop body is executed + // only when index variable is equal to split value. + IndVar->replaceAllUsesWith(SD.SplitValue); + + // Remove Latch to Header edge. BasicBlock *Latch = L->getLoopLatch(); BasicBlock *LatchSucc = NULL; BranchInst *BR = dyn_cast(Latch->getTerminator()); From baldrick at free.fr Mon Aug 20 16:03:35 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 20 Aug 2007 21:03:35 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41196 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200708202103.l7KL3Zbx029339@zion.cs.uiuc.edu> Author: baldrick Date: Mon Aug 20 16:03:35 2007 New Revision: 41196 URL: http://llvm.org/viewvc/llvm-project?rev=41196&view=rev Log: Fix 2002-08-19-RecursiveLocals.c. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=41196&r1=41195&r2=41196&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Mon Aug 20 16:03:35 2007 @@ -1061,7 +1061,7 @@ } else { // If the global has a name, prevent multiple vars with the same name from // being created. - GlobalVariable *GVE = TheModule->getGlobalVariable(Name); + GlobalVariable *GVE = TheModule->getGlobalVariable(Name, true); if (GVE == 0) { GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage,0, From asl at math.spbu.ru Mon Aug 20 16:17:26 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Mon, 20 Aug 2007 21:17:26 -0000 Subject: [llvm-commits] [llvm] r41197 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolutionExpander.h lib/Analysis/LoopPass.cpp lib/Analysis/ScalarEvolutionExpander.cpp Message-ID: <200708202117.l7KLHQS6030431@zion.cs.uiuc.edu> Author: asl Date: Mon Aug 20 16:17:26 2007 New Revision: 41197 URL: http://llvm.org/viewvc/llvm-project?rev=41197&view=rev Log: - Use correct header for SCEV inside LoopPass.cpp - Move SCEVExpander::expand() out-of-line workarounding possible toolchain bug Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h llvm/trunk/lib/Analysis/LoopPass.cpp llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h?rev=41197&r1=41196&r2=41197&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h Mon Aug 20 16:17:26 2007 @@ -93,17 +93,8 @@ static Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, Instruction *&InsertPt); protected: - Value *expand(SCEV *S) { - // Check to see if we already expanded this. - std::map::iterator I = InsertedExpressions.find(S); - if (I != InsertedExpressions.end()) - return I->second; - - Value *V = visit(S); - InsertedExpressions[S] = V; - return V; - } - + Value *expand(SCEV *S); + Value *visitConstant(SCEVConstant *S) { return S->getValue(); } Modified: llvm/trunk/lib/Analysis/LoopPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopPass.cpp?rev=41197&r1=41196&r2=41197&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LoopPass.cpp (original) +++ llvm/trunk/lib/Analysis/LoopPass.cpp Mon Aug 20 16:17:26 2007 @@ -14,7 +14,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/ScalarEvolutionExpander.h" +#include "llvm/Analysis/ScalarEvolution.h" using namespace llvm; //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=41197&r1=41196&r2=41197&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Mon Aug 20 16:17:26 2007 @@ -207,3 +207,15 @@ return expand(V); } + +Value *SCEVExpander::expand(SCEV *S) { + // Check to see if we already expanded this. + std::map::iterator I = InsertedExpressions.find(S); + if (I != InsertedExpressions.end()) + return I->second; + + Value *V = visit(S); + InsertedExpressions[S] = V; + return V; +} + From lattner at apple.com Mon Aug 20 16:18:41 2007 From: lattner at apple.com (Tanya Lattner) Date: Mon, 20 Aug 2007 14:18:41 -0700 Subject: [llvm-commits] [llvm] r41192 - /llvm/trunk/include/llvm/Support/PassNameParser.h In-Reply-To: <200708201954.l7KJs4sl026117@zion.cs.uiuc.edu> References: <200708201954.l7KJs4sl026117@zion.cs.uiuc.edu> Message-ID: <05AD84F9-7FC7-42AA-984D-B5994B023DD3@apple.com> These are good comments, but could you use the doxygen style comments "///" so that it will show up in doxygen? Thanks, Tanya On Aug 20, 2007, at 12:54 PM, David Greene wrote: > Author: greened > Date: Mon Aug 20 14:54:01 2007 > New Revision: 41192 > > URL: http://llvm.org/viewvc/llvm-project?rev=41192&view=rev > Log: > > Add FilteredPassNameParser along with PassArgFilter to filter passes > based on their Arg members. > > > > Modified: > llvm/trunk/include/llvm/Support/PassNameParser.h > > Modified: llvm/trunk/include/llvm/Support/PassNameParser.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ > Support/PassNameParser.h?rev=41192&r1=41191&r2=41192&view=diff > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/Support/PassNameParser.h (original) > +++ llvm/trunk/include/llvm/Support/PassNameParser.h Mon Aug 20 > 14:54:01 2007 > @@ -24,9 +24,9 @@ > #define LLVM_SUPPORT_PASS_NAME_PARSER_H > > #include "llvm/Support/CommandLine.h" > -#include "llvm/Support/Debug.h" > #include "llvm/Pass.h" > #include > +#include > > namespace llvm { > > @@ -89,6 +89,44 @@ > } > }; > > -} // End llvm namespace > +// > ===------------------------------------------------------------------- > ---===// > +// FilteredPassNameParser class - Make use of the pass registration > +// mechanism to automatically add a command line argument to opt for > +// each pass that satisfies a filter criteria. Filter should return > +// true for passes to be registered as command-line options. > +// > +template > +class FilteredPassNameParser : public PassNameParser { > +private: > + Filter filter; > > +public: > + bool ignorablePassImpl(const PassInfo *P) const { return !filter > (*P); } > +}; > + > +// > ===------------------------------------------------------------------- > ---===// > +// PassArgFilter - A filter for use with PassNameFilterParser that > only > +// accepts a Pass whose Arg matches certain strings. > +// > +// Use like this: > +// > +// extern const char AllowedPassArgs[] = "-anders_aa -dse"; > +// > +// static cl::list< > +// const PassInfo*, > +// bool, > +// FilteredPassNameParser > > > +// PassList(cl::desc("LLVM optimizations available:")); > +// > +// Only the -anders_aa and -dse options will be available to the > user. > +// > +template > +class PassArgFilter { > +public: > + bool operator()(const PassInfo &P) const { > + return(std::strstr(Args, P.getPassArgument())); > + } > +}; > + > +} // End llvm namespace > #endif > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From sabre at nondot.org Mon Aug 20 16:22:48 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Aug 2007 21:22:48 -0000 Subject: [llvm-commits] [llvm] r41198 - /llvm/trunk/include/llvm/ADT/SmallVector.h Message-ID: <200708202122.l7KLMm2f030982@zion.cs.uiuc.edu> Author: lattner Date: Mon Aug 20 16:22:48 2007 New Revision: 41198 URL: http://llvm.org/viewvc/llvm-project?rev=41198&view=rev Log: add reverse iterators to smallvector Modified: llvm/trunk/include/llvm/ADT/SmallVector.h Modified: llvm/trunk/include/llvm/ADT/SmallVector.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallVector.h?rev=41198&r1=41197&r2=41198&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/SmallVector.h (original) +++ llvm/trunk/include/llvm/ADT/SmallVector.h Mon Aug 20 16:22:48 2007 @@ -14,8 +14,8 @@ #ifndef LLVM_ADT_SMALLVECTOR_H #define LLVM_ADT_SMALLVECTOR_H +#include "llvm/ADT/iterator" #include -#include #include #ifdef _MSC_VER @@ -90,18 +90,29 @@ typedef size_t size_type; typedef T* iterator; typedef const T* const_iterator; + + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef T& reference; typedef const T& const_reference; bool empty() const { return Begin == End; } size_type size() const { return End-Begin; } - + + // forward iterator creation methods. iterator begin() { return Begin; } const_iterator begin() const { return Begin; } - iterator end() { return End; } const_iterator end() const { return End; } + // reverse iterator creation methods. + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin());} + + reference operator[](unsigned idx) { return Begin[idx]; } From sabre at nondot.org Mon Aug 20 16:31:09 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Aug 2007 21:31:09 -0000 Subject: [llvm-commits] [llvm] r41199 - /llvm/trunk/include/llvm/Function.h Message-ID: <200708202131.l7KLV9I6031699@zion.cs.uiuc.edu> Author: lattner Date: Mon Aug 20 16:31:08 2007 New Revision: 41199 URL: http://llvm.org/viewvc/llvm-project?rev=41199&view=rev Log: clarify precedence, no functionality change. Modified: llvm/trunk/include/llvm/Function.h Modified: llvm/trunk/include/llvm/Function.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Function.h?rev=41199&r1=41198&r2=41199&view=diff ============================================================================== --- llvm/trunk/include/llvm/Function.h (original) +++ llvm/trunk/include/llvm/Function.h Mon Aug 20 16:31:08 2007 @@ -138,7 +138,7 @@ /// calling conventions are defined in CallingConv.h. unsigned getCallingConv() const { return SubclassData >> 1; } void setCallingConv(unsigned CC) { - SubclassData = (SubclassData & 1) | CC << 1; + SubclassData = (SubclassData & 1) | (CC << 1); } /// Obtains a constant pointer to the ParamAttrsList object which holds the From sabre at nondot.org Mon Aug 20 17:49:32 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 20 Aug 2007 22:49:32 -0000 Subject: [llvm-commits] [llvm] r41203 - in /llvm/trunk: include/llvm/ADT/APFloat.h include/llvm/ADT/APInt.h lib/Support/APFloat.cpp lib/Support/APInt.cpp Message-ID: <200708202249.l7KMnWb5002849@zion.cs.uiuc.edu> Author: lattner Date: Mon Aug 20 17:49:32 2007 New Revision: 41203 URL: http://llvm.org/viewvc/llvm-project?rev=41203&view=rev Log: initial checkin of Neil's APFloat work. Added: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/include/llvm/ADT/APInt.h llvm/trunk/lib/Support/APInt.cpp Added: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=41203&view=auto ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (added) +++ llvm/trunk/include/llvm/ADT/APFloat.h Mon Aug 20 17:49:32 2007 @@ -0,0 +1,258 @@ +//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Neil Booth and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares a class to represent arbitrary precision floating +// point values and provide a variety of arithmetic operations on them. +// +//===----------------------------------------------------------------------===// + +/* A self-contained host- and target-independent arbitrary-precision + floating-point software implementation using bignum integer + arithmetic, as provided by static functions in the APInt class. + The library will work with bignum integers whose parts are any + unsigned type at least 16 bits wide. 64 bits is recommended. + + Written for clarity rather than speed, in particular with a view + to use in the front-end of a cross compiler so that target + arithmetic can be correctly performed on the host. Performance + should nonetheless be reasonable, particularly for its intended + use. It may be useful as a base implementation for a run-time + library during development of a faster target-specific one. + + All 5 rounding modes in the IEEE-754R draft are handled correctly + for all implemented operations. Currently implemented operations + are add, subtract, multiply, divide, fused-multiply-add, + conversion-to-float, conversion-to-integer and + conversion-from-integer. New rounding modes (e.g. away from zero) + can be added with three or four lines of code. The library reads + and correctly rounds hexadecimal floating point numbers as per + C99; syntax is required to have been validated by the caller. + Conversion from decimal is not currently implemented. + + Four formats are built-in: IEEE single precision, double + precision, quadruple precision, and x87 80-bit extended double + (when operating with full extended precision). Adding a new + format that obeys IEEE semantics only requires adding two lines of + code: a declaration and definition of the format. + + All operations return the status of that operation as an exception + bit-mask, so multiple operations can be done consecutively with + their results or-ed together. The returned status can be useful + for compiler diagnostics; e.g., inexact, underflow and overflow + can be easily diagnosed on constant folding, and compiler + optimizers can determine what exceptions would be raised by + folding operations and optimize, or perhaps not optimize, + accordingly. + + At present, underflow tininess is detected after rounding; it + should be straight forward to add support for the before-rounding + case too. + + Non-zero finite numbers are represented internally as a sign bit, + a 16-bit signed exponent, and the significand as an array of + integer parts. After normalization of a number of precision P the + exponent is within the range of the format, and if the number is + not denormal the P-th bit of the significand is set as an explicit + integer bit. For denormals the most significant bit is shifted + right so that the exponent is maintained at the format's minimum, + so that the smallest denormal has just the least significant bit + of the significand set. The sign of zeroes and infinities is + significant; the exponent and significand of such numbers is + indeterminate and meaningless. For QNaNs the sign bit, as well as + the exponent and significand are indeterminate and meaningless. + + TODO + ==== + + Some features that may or may not be worth adding: + + Conversions to and from decimal strings (hard). + + Conversions to hexadecimal string. + + Read and write IEEE-format in-memory representations. + + Optional ability to detect underflow tininess before rounding. + + New formats: x87 in single and double precision mode (IEEE apart + from extended exponent range) and IBM two-double extended + precision (hard). + + New operations: sqrt, copysign, nextafter, nexttoward. +*/ + +#ifndef LLVM_FLOAT_H +#define LLVM_FLOAT_H + +// APInt contains static functions implementing bignum arithmetic. +#include "llvm/ADT/APInt.h" + +namespace llvm { + + /* Exponents are stored as signed numbers. */ + typedef signed short exponent_t; + + struct fltSemantics; + + /* When bits of a floating point number are truncated, this enum is + used to indicate what fraction of the LSB those bits represented. + It essentially combines the roles of guard and sticky bits. */ + enum lostFraction { // Example of truncated bits: + lfExactlyZero, // 000000 + lfLessThanHalf, // 0xxxxx x's not all zero + lfExactlyHalf, // 100000 + lfMoreThanHalf // 1xxxxx x's not all zero + }; + + class APFloat { + public: + + /* We support the following floating point semantics. */ + static const fltSemantics IEEEsingle; + static const fltSemantics IEEEdouble; + static const fltSemantics IEEEquad; + static const fltSemantics x87DoubleExtended; + + static unsigned int semanticsPrecision(const fltSemantics &); + + /* Floating point numbers have a four-state comparison relation. */ + enum cmpResult { + cmpLessThan, + cmpEqual, + cmpGreaterThan, + cmpUnordered + }; + + /* IEEE-754R gives five rounding modes. */ + enum roundingMode { + rmNearestTiesToEven, + rmTowardPositive, + rmTowardNegative, + rmTowardZero, + rmNearestTiesToAway + }; + + /* Operation status. opUnderflow or opOverflow are always returned + or-ed with opInexact. */ + enum opStatus { + opOK = 0x00, + opInvalidOp = 0x01, + opDivByZero = 0x02, + opOverflow = 0x04, + opUnderflow = 0x08, + opInexact = 0x10 + }; + + /* Category of internally-represented number. */ + enum fltCategory { + fcInfinity, + fcQNaN, + fcNormal, + fcZero + }; + + /* Constructors. */ + APFloat(const fltSemantics &, const char *); + APFloat(const fltSemantics &, integerPart); + APFloat(const fltSemantics &, fltCategory, bool negative); + APFloat(const APFloat &); + ~APFloat(); + + /* Arithmetic. */ + opStatus add(const APFloat &, roundingMode); + opStatus subtract(const APFloat &, roundingMode); + opStatus multiply(const APFloat &, roundingMode); + opStatus divide(const APFloat &, roundingMode); + opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode); + void changeSign(); + + /* Conversions. */ + opStatus convert(const fltSemantics &, roundingMode); + opStatus convertToInteger(integerPart *, unsigned int, bool, + roundingMode) const; + opStatus convertFromInteger(const integerPart *, unsigned int, bool, + roundingMode); + opStatus convertFromString(const char *, roundingMode); + + /* Comparison with another floating point number. */ + cmpResult compare(const APFloat &) const; + + /* Simple queries. */ + fltCategory getCategory() const { return category; } + const fltSemantics &getSemantics() const { return *semantics; } + bool isZero() const { return category == fcZero; } + bool isNonZero() const { return category != fcZero; } + bool isNegative() const { return sign; } + + APFloat& operator=(const APFloat &); + + private: + + /* Trivial queries. */ + integerPart *significandParts(); + const integerPart *significandParts() const; + unsigned int partCount() const; + + /* Significand operations. */ + integerPart addSignificand(const APFloat &); + integerPart subtractSignificand(const APFloat &, integerPart); + lostFraction addOrSubtractSignificand(const APFloat &, bool subtract); + lostFraction multiplySignificand(const APFloat &, const APFloat *); + lostFraction divideSignificand(const APFloat &); + void incrementSignificand(); + void initialize(const fltSemantics *); + void shiftSignificandLeft(unsigned int); + lostFraction shiftSignificandRight(unsigned int); + unsigned int significandLSB() const; + unsigned int significandMSB() const; + void zeroSignificand(); + + /* Arithmetic on special values. */ + opStatus addOrSubtractSpecials(const APFloat &, bool subtract); + opStatus divideSpecials(const APFloat &); + opStatus multiplySpecials(const APFloat &); + + /* Miscellany. */ + opStatus normalize(roundingMode, lostFraction); + opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract); + cmpResult compareAbsoluteValue(const APFloat &) const; + opStatus handleOverflow(roundingMode); + bool roundAwayFromZero(roundingMode, lostFraction); + opStatus convertFromUnsignedInteger(integerPart *, unsigned int, + roundingMode); + lostFraction combineLostFractions(lostFraction, lostFraction); + opStatus convertFromHexadecimalString(const char *, roundingMode); + + void assign(const APFloat &); + void copySignificand(const APFloat &); + void freeSignificand(); + + /* What kind of semantics does this value obey? */ + const fltSemantics *semantics; + + /* Significand - the fraction with an explicit integer bit. Must be + at least one bit wider than the target precision. */ + union Significand + { + integerPart part; + integerPart *parts; + } significand; + + /* The exponent - a signed number. */ + exponent_t exponent; + + /* What kind of floating point number this is. */ + fltCategory category: 2; + + /* The sign bit of this number. */ + unsigned int sign: 1; + }; +} /* namespace llvm */ + +#endif /* LLVM_FLOAT_H */ Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=41203&r1=41202&r2=41203&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Mon Aug 20 17:49:32 2007 @@ -19,9 +19,7 @@ #include #include -#define HOST_CHAR_BIT 8 -#define compileTimeAssert(cond) extern int CTAssert[(cond) ? 1 : -1] -#define integerPartWidth (HOST_CHAR_BIT * sizeof(llvm::integerPart)) +#define COMPILE_TIME_ASSERT(cond) extern int CTAssert[(cond) ? 1 : -1] namespace llvm { @@ -29,6 +27,9 @@ bignum. */ typedef uint64_t integerPart; + const unsigned int host_char_bit = 8; + const unsigned int integerPartWidth = host_char_bit * sizeof(integerPart); + //===----------------------------------------------------------------------===// // APInt Class //===----------------------------------------------------------------------===// Added: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=41203&view=auto ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (added) +++ llvm/trunk/lib/Support/APFloat.cpp Mon Aug 20 17:49:32 2007 @@ -0,0 +1,1488 @@ +//===-- APFloat.cpp - Implement APFloat class -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Neil Booth and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a class to represent arbitrary precision floating +// point values and provide a variety of arithmetic operations on them. +// +//===----------------------------------------------------------------------===// + +#include +#include "llvm/ADT/APFloat.h" + +using namespace llvm; + +#define convolve(lhs, rhs) ((lhs) * 4 + (rhs)) + +/* Assumed in hexadecimal significand parsing. */ +COMPILE_TIME_ASSERT(integerPartWidth % 4 == 0); + +namespace llvm { + + /* Represents floating point arithmetic semantics. */ + struct fltSemantics { + /* The largest E such that 2^E is representable; this matches the + definition of IEEE 754. */ + exponent_t maxExponent; + + /* The smallest E such that 2^E is a normalized number; this + matches the definition of IEEE 754. */ + exponent_t minExponent; + + /* Number of bits in the significand. This includes the integer + bit. */ + unsigned char precision; + + /* If the target format has an implicit integer bit. */ + bool implicitIntegerBit; + }; + + const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, true }; + const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true }; + const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true }; + const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, false }; +} + +/* Put a bunch of private, handy routines in an anonymous namespace. */ +namespace { + + inline unsigned int + partCountForBits(unsigned int bits) + { + return ((bits) + integerPartWidth - 1) / integerPartWidth; + } + + unsigned int + digitValue(unsigned int c) + { + unsigned int r; + + r = c - '0'; + if(r <= 9) + return r; + + return -1U; + } + + unsigned int + hexDigitValue (unsigned int c) + { + unsigned int r; + + r = c - '0'; + if(r <= 9) + return r; + + r = c - 'A'; + if(r <= 5) + return r + 10; + + r = c - 'a'; + if(r <= 5) + return r + 10; + + return -1U; + } + + /* This is ugly and needs cleaning up, but I don't immediately see + how whilst remaining safe. */ + static int + totalExponent(const char *p, int exponentAdjustment) + { + integerPart unsignedExponent; + bool negative, overflow; + long exponent; + + /* Move past the exponent letter and sign to the digits. */ + p++; + negative = *p == '-'; + if(*p == '-' || *p == '+') + p++; + + unsignedExponent = 0; + overflow = false; + for(;;) { + unsigned int value; + + value = digitValue(*p); + if(value == -1U) + break; + + p++; + unsignedExponent = unsignedExponent * 10 + value; + if(unsignedExponent > 65535) + overflow = true; + } + + if(exponentAdjustment > 65535 || exponentAdjustment < -65536) + overflow = true; + + if(!overflow) { + exponent = unsignedExponent; + if(negative) + exponent = -exponent; + exponent += exponentAdjustment; + if(exponent > 65535 || exponent < -65536) + overflow = true; + } + + if(overflow) + exponent = negative ? -65536: 65535; + + return exponent; + } + + const char * + skipLeadingZeroesAndAnyDot(const char *p, const char **dot) + { + *dot = 0; + while(*p == '0') + p++; + + if(*p == '.') { + *dot = p++; + while(*p == '0') + p++; + } + + return p; + } + + /* Return the trailing fraction of a hexadecimal number. + DIGITVALUE is the first hex digit of the fraction, P points to + the next digit. */ + lostFraction + trailingHexadecimalFraction(const char *p, unsigned int digitValue) + { + unsigned int hexDigit; + + /* If the first trailing digit isn't 0 or 8 we can work out the + fraction immediately. */ + if(digitValue > 8) + return lfMoreThanHalf; + else if(digitValue < 8 && digitValue > 0) + return lfLessThanHalf; + + /* Otherwise we need to find the first non-zero digit. */ + while(*p == '0') + p++; + + hexDigit = hexDigitValue(*p); + + /* If we ran off the end it is exactly zero or one-half, otherwise + a little more. */ + if(hexDigit == -1U) + return digitValue == 0 ? lfExactlyZero: lfExactlyHalf; + else + return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf; + } + + /* Return the fraction lost were a bignum truncated. */ + lostFraction + lostFractionThroughTruncation(integerPart *parts, + unsigned int partCount, + unsigned int bits) + { + unsigned int lsb; + + lsb = APInt::tcLSB(parts, partCount); + + /* Note this is guaranteed true if bits == 0, or LSB == -1U. */ + if(bits <= lsb) + return lfExactlyZero; + if(bits == lsb + 1) + return lfExactlyHalf; + if(bits <= partCount * integerPartWidth + && APInt::tcExtractBit(parts, bits - 1)) + return lfMoreThanHalf; + + return lfLessThanHalf; + } + + /* Shift DST right BITS bits noting lost fraction. */ + lostFraction + shiftRight(integerPart *dst, unsigned int parts, unsigned int bits) + { + lostFraction lost_fraction; + + lost_fraction = lostFractionThroughTruncation(dst, parts, bits); + + APInt::tcShiftRight(dst, parts, bits); + + return lost_fraction; + } +} + +/* Constructors. */ +void +APFloat::initialize(const fltSemantics *ourSemantics) +{ + unsigned int count; + + semantics = ourSemantics; + count = partCount(); + if(count > 1) + significand.parts = new integerPart[count]; +} + +void +APFloat::freeSignificand() +{ + if(partCount() > 1) + delete [] significand.parts; +} + +void +APFloat::assign(const APFloat &rhs) +{ + assert(semantics == rhs.semantics); + + sign = rhs.sign; + category = rhs.category; + exponent = rhs.exponent; + if(category == fcNormal) + copySignificand(rhs); +} + +void +APFloat::copySignificand(const APFloat &rhs) +{ + assert(category == fcNormal); + assert(rhs.partCount() >= partCount()); + + APInt::tcAssign(significandParts(), rhs.significandParts(), + partCount()); +} + +APFloat & +APFloat::operator=(const APFloat &rhs) +{ + if(this != &rhs) { + if(semantics != rhs.semantics) { + freeSignificand(); + initialize(rhs.semantics); + } + assign(rhs); + } + + return *this; +} + +APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) +{ + initialize(&ourSemantics); + sign = 0; + zeroSignificand(); + exponent = ourSemantics.precision - 1; + significandParts()[0] = value; + normalize(rmNearestTiesToEven, lfExactlyZero); +} + +APFloat::APFloat(const fltSemantics &ourSemantics, + fltCategory ourCategory, bool negative) +{ + initialize(&ourSemantics); + category = ourCategory; + sign = negative; + if(category == fcNormal) + category = fcZero; +} + +APFloat::APFloat(const fltSemantics &ourSemantics, const char *text) +{ + initialize(&ourSemantics); + convertFromString(text, rmNearestTiesToEven); +} + +APFloat::APFloat(const APFloat &rhs) +{ + initialize(rhs.semantics); + assign(rhs); +} + +APFloat::~APFloat() +{ + freeSignificand(); +} + +unsigned int +APFloat::partCount() const +{ + return partCountForBits(semantics->precision + 1); +} + +unsigned int +APFloat::semanticsPrecision(const fltSemantics &semantics) +{ + return semantics.precision; +} + +const integerPart * +APFloat::significandParts() const +{ + return const_cast(this)->significandParts(); +} + +integerPart * +APFloat::significandParts() +{ + assert(category == fcNormal); + + if(partCount() > 1) + return significand.parts; + else + return &significand.part; +} + +/* Combine the effect of two lost fractions. */ +lostFraction +APFloat::combineLostFractions(lostFraction moreSignificant, + lostFraction lessSignificant) +{ + if(lessSignificant != lfExactlyZero) { + if(moreSignificant == lfExactlyZero) + moreSignificant = lfLessThanHalf; + else if(moreSignificant == lfExactlyHalf) + moreSignificant = lfMoreThanHalf; + } + + return moreSignificant; +} + +void +APFloat::zeroSignificand() +{ + category = fcNormal; + APInt::tcSet(significandParts(), 0, partCount()); +} + +/* Increment an fcNormal floating point number's significand. */ +void +APFloat::incrementSignificand() +{ + integerPart carry; + + carry = APInt::tcIncrement(significandParts(), partCount()); + + /* Our callers should never cause us to overflow. */ + assert(carry == 0); +} + +/* Add the significand of the RHS. Returns the carry flag. */ +integerPart +APFloat::addSignificand(const APFloat &rhs) +{ + integerPart *parts; + + parts = significandParts(); + + assert(semantics == rhs.semantics); + assert(exponent == rhs.exponent); + + return APInt::tcAdd(parts, rhs.significandParts(), 0, partCount()); +} + +/* Subtract the significand of the RHS with a borrow flag. Returns + the borrow flag. */ +integerPart +APFloat::subtractSignificand(const APFloat &rhs, integerPart borrow) +{ + integerPart *parts; + + parts = significandParts(); + + assert(semantics == rhs.semantics); + assert(exponent == rhs.exponent); + + return APInt::tcSubtract(parts, rhs.significandParts(), borrow, + partCount()); +} + +/* Multiply the significand of the RHS. If ADDEND is non-NULL, add it + on to the full-precision result of the multiplication. Returns the + lost fraction. */ +lostFraction +APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) +{ + unsigned int omsb; // One, not zero, based MSB. + unsigned int partsCount, newPartsCount, precision; + integerPart *lhsSignificand; + integerPart scratch[4]; + integerPart *fullSignificand; + lostFraction lost_fraction; + + assert(semantics == rhs.semantics); + + precision = semantics->precision; + newPartsCount = partCountForBits(precision * 2); + + if(newPartsCount > 4) + fullSignificand = new integerPart[newPartsCount]; + else + fullSignificand = scratch; + + lhsSignificand = significandParts(); + partsCount = partCount(); + + APInt::tcFullMultiply(fullSignificand, lhsSignificand, + rhs.significandParts(), partsCount); + + lost_fraction = lfExactlyZero; + omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1; + exponent += rhs.exponent; + + if(addend) { + Significand savedSignificand = significand; + const fltSemantics *savedSemantics = semantics; + fltSemantics extendedSemantics; + opStatus status; + unsigned int extendedPrecision; + + /* Normalize our MSB. */ + extendedPrecision = precision + precision - 1; + if(omsb != extendedPrecision) + { + APInt::tcShiftLeft(fullSignificand, newPartsCount, + extendedPrecision - omsb); + exponent -= extendedPrecision - omsb; + } + + /* Create new semantics. */ + extendedSemantics = *semantics; + extendedSemantics.precision = extendedPrecision; + + if(newPartsCount == 1) + significand.part = fullSignificand[0]; + else + significand.parts = fullSignificand; + semantics = &extendedSemantics; + + APFloat extendedAddend(*addend); + status = extendedAddend.convert(extendedSemantics, rmTowardZero); + assert(status == opOK); + lost_fraction = addOrSubtractSignificand(extendedAddend, false); + + /* Restore our state. */ + if(newPartsCount == 1) + fullSignificand[0] = significand.part; + significand = savedSignificand; + semantics = savedSemantics; + + omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1; + } + + exponent -= (precision - 1); + + if(omsb > precision) { + unsigned int bits, significantParts; + lostFraction lf; + + bits = omsb - precision; + significantParts = partCountForBits(omsb); + lf = shiftRight(fullSignificand, significantParts, bits); + lost_fraction = combineLostFractions(lf, lost_fraction); + exponent += bits; + } + + APInt::tcAssign(lhsSignificand, fullSignificand, partsCount); + + if(newPartsCount > 4) + delete [] fullSignificand; + + return lost_fraction; +} + +/* Multiply the significands of LHS and RHS to DST. */ +lostFraction +APFloat::divideSignificand(const APFloat &rhs) +{ + unsigned int bit, i, partsCount; + const integerPart *rhsSignificand; + integerPart *lhsSignificand, *dividend, *divisor; + integerPart scratch[4]; + lostFraction lost_fraction; + + assert(semantics == rhs.semantics); + + lhsSignificand = significandParts(); + rhsSignificand = rhs.significandParts(); + partsCount = partCount(); + + if(partsCount > 2) + dividend = new integerPart[partsCount * 2]; + else + dividend = scratch; + + divisor = dividend + partsCount; + + /* Copy the dividend and divisor as they will be modified in-place. */ + for(i = 0; i < partsCount; i++) { + dividend[i] = lhsSignificand[i]; + divisor[i] = rhsSignificand[i]; + lhsSignificand[i] = 0; + } + + exponent -= rhs.exponent; + + unsigned int precision = semantics->precision; + + /* Normalize the divisor. */ + bit = precision - APInt::tcMSB(divisor, partsCount) - 1; + if(bit) { + exponent += bit; + APInt::tcShiftLeft(divisor, partsCount, bit); + } + + /* Normalize the dividend. */ + bit = precision - APInt::tcMSB(dividend, partsCount) - 1; + if(bit) { + exponent -= bit; + APInt::tcShiftLeft(dividend, partsCount, bit); + } + + if(APInt::tcCompare(dividend, divisor, partsCount) < 0) { + exponent--; + APInt::tcShiftLeft(dividend, partsCount, 1); + assert(APInt::tcCompare(dividend, divisor, partsCount) >= 0); + } + + /* Long division. */ + for(bit = precision; bit; bit -= 1) { + if(APInt::tcCompare(dividend, divisor, partsCount) >= 0) { + APInt::tcSubtract(dividend, divisor, 0, partsCount); + APInt::tcSetBit(lhsSignificand, bit - 1); + } + + APInt::tcShiftLeft(dividend, partsCount, 1); + } + + /* Figure out the lost fraction. */ + int cmp = APInt::tcCompare(dividend, divisor, partsCount); + + if(cmp > 0) + lost_fraction = lfMoreThanHalf; + else if(cmp == 0) + lost_fraction = lfExactlyHalf; + else if(APInt::tcIsZero(dividend, partsCount)) + lost_fraction = lfExactlyZero; + else + lost_fraction = lfLessThanHalf; + + if(partsCount > 2) + delete [] dividend; + + return lost_fraction; +} + +unsigned int +APFloat::significandMSB() const +{ + return APInt::tcMSB(significandParts(), partCount()); +} + +unsigned int +APFloat::significandLSB() const +{ + return APInt::tcLSB(significandParts(), partCount()); +} + +/* Note that a zero result is NOT normalized to fcZero. */ +lostFraction +APFloat::shiftSignificandRight(unsigned int bits) +{ + /* Our exponent should not overflow. */ + assert((exponent_t) (exponent + bits) >= exponent); + + exponent += bits; + + return shiftRight(significandParts(), partCount(), bits); +} + +/* Shift the significand left BITS bits, subtract BITS from its exponent. */ +void +APFloat::shiftSignificandLeft(unsigned int bits) +{ + assert(bits < semantics->precision); + + if(bits) { + unsigned int partsCount = partCount(); + + APInt::tcShiftLeft(significandParts(), partsCount, bits); + exponent -= bits; + + assert(!APInt::tcIsZero(significandParts(), partsCount)); + } +} + +APFloat::cmpResult +APFloat::compareAbsoluteValue(const APFloat &rhs) const +{ + int compare; + + assert(semantics == rhs.semantics); + assert(category == fcNormal); + assert(rhs.category == fcNormal); + + compare = exponent - rhs.exponent; + + /* If exponents are equal, do an unsigned bignum comparison of the + significands. */ + if(compare == 0) + compare = APInt::tcCompare(significandParts(), rhs.significandParts(), + partCount()); + + if(compare > 0) + return cmpGreaterThan; + else if(compare < 0) + return cmpLessThan; + else + return cmpEqual; +} + +/* Handle overflow. Sign is preserved. We either become infinity or + the largest finite number. */ +APFloat::opStatus +APFloat::handleOverflow(roundingMode rounding_mode) +{ + /* Infinity? */ + if(rounding_mode == rmNearestTiesToEven + || rounding_mode == rmNearestTiesToAway + || (rounding_mode == rmTowardPositive && !sign) + || (rounding_mode == rmTowardNegative && sign)) + { + category = fcInfinity; + return (opStatus) (opOverflow | opInexact); + } + + /* Otherwise we become the largest finite number. */ + category = fcNormal; + exponent = semantics->maxExponent; + APInt::tcSetLeastSignificantBits(significandParts(), partCount(), + semantics->precision); + + return opInexact; +} + +/* This routine must work for fcZero of both signs, and fcNormal + numbers. */ +bool +APFloat::roundAwayFromZero(roundingMode rounding_mode, + lostFraction lost_fraction) +{ + /* QNaNs and infinities should not have lost fractions. */ + assert(category == fcNormal || category == fcZero); + + /* Our caller has already handled this case. */ + assert(lost_fraction != lfExactlyZero); + + switch(rounding_mode) { + default: + assert(0); + + case rmNearestTiesToAway: + return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf; + + case rmNearestTiesToEven: + if(lost_fraction == lfMoreThanHalf) + return true; + + /* Our zeroes don't have a significand to test. */ + if(lost_fraction == lfExactlyHalf && category != fcZero) + return significandParts()[0] & 1; + + return false; + + case rmTowardZero: + return false; + + case rmTowardPositive: + return sign == false; + + case rmTowardNegative: + return sign == true; + } +} + +APFloat::opStatus +APFloat::normalize(roundingMode rounding_mode, + lostFraction lost_fraction) +{ + unsigned int omsb; /* One, not zero, based MSB. */ + int exponentChange; + + if(category != fcNormal) + return opOK; + + /* Before rounding normalize the exponent of fcNormal numbers. */ + omsb = significandMSB() + 1; + + if(omsb) { + /* OMSB is numbered from 1. We want to place it in the integer + bit numbered PRECISON if possible, with a compensating change in + the exponent. */ + exponentChange = omsb - semantics->precision; + + /* If the resulting exponent is too high, overflow according to + the rounding mode. */ + if(exponent + exponentChange > semantics->maxExponent) + return handleOverflow(rounding_mode); + + /* Subnormal numbers have exponent minExponent, and their MSB + is forced based on that. */ + if(exponent + exponentChange < semantics->minExponent) + exponentChange = semantics->minExponent - exponent; + + /* Shifting left is easy as we don't lose precision. */ + if(exponentChange < 0) { + assert(lost_fraction == lfExactlyZero); + + shiftSignificandLeft(-exponentChange); + + return opOK; + } + + if(exponentChange > 0) { + lostFraction lf; + + /* Shift right and capture any new lost fraction. */ + lf = shiftSignificandRight(exponentChange); + + lost_fraction = combineLostFractions(lf, lost_fraction); + + /* Keep OMSB up-to-date. */ + if(omsb > (unsigned) exponentChange) + omsb -= (unsigned) exponentChange; + else + omsb = 0; + } + } + + /* Now round the number according to rounding_mode given the lost + fraction. */ + + /* As specified in IEEE 754, since we do not trap we do not report + underflow for exact results. */ + if(lost_fraction == lfExactlyZero) { + /* Canonicalize zeroes. */ + if(omsb == 0) + category = fcZero; + + return opOK; + } + + /* Increment the significand if we're rounding away from zero. */ + if(roundAwayFromZero(rounding_mode, lost_fraction)) { + if(omsb == 0) + exponent = semantics->minExponent; + + incrementSignificand(); + omsb = significandMSB() + 1; + + /* Did the significand increment overflow? */ + if(omsb == (unsigned) semantics->precision + 1) { + /* Renormalize by incrementing the exponent and shifting our + significand right one. However if we already have the + maximum exponent we overflow to infinity. */ + if(exponent == semantics->maxExponent) { + category = fcInfinity; + + return (opStatus) (opOverflow | opInexact); + } + + shiftSignificandRight(1); + + return opInexact; + } + } + + /* The normal case - we were and are not denormal, and any + significand increment above didn't overflow. */ + if(omsb == semantics->precision) + return opInexact; + + /* We have a non-zero denormal. */ + assert(omsb < semantics->precision); + assert(exponent == semantics->minExponent); + + /* Canonicalize zeroes. */ + if(omsb == 0) + category = fcZero; + + /* The fcZero case is a denormal that underflowed to zero. */ + return (opStatus) (opUnderflow | opInexact); +} + +APFloat::opStatus +APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) +{ + switch(convolve(category, rhs.category)) { + default: + assert(0); + + case convolve(fcQNaN, fcZero): + case convolve(fcQNaN, fcNormal): + case convolve(fcQNaN, fcInfinity): + case convolve(fcQNaN, fcQNaN): + case convolve(fcNormal, fcZero): + case convolve(fcInfinity, fcNormal): + case convolve(fcInfinity, fcZero): + return opOK; + + case convolve(fcZero, fcQNaN): + case convolve(fcNormal, fcQNaN): + case convolve(fcInfinity, fcQNaN): + category = fcQNaN; + return opOK; + + case convolve(fcNormal, fcInfinity): + case convolve(fcZero, fcInfinity): + category = fcInfinity; + sign = rhs.sign ^ subtract; + return opOK; + + case convolve(fcZero, fcNormal): + assign(rhs); + sign = rhs.sign ^ subtract; + return opOK; + + case convolve(fcZero, fcZero): + /* Sign depends on rounding mode; handled by caller. */ + return opOK; + + case convolve(fcInfinity, fcInfinity): + /* Differently signed infinities can only be validly + subtracted. */ + if(sign ^ rhs.sign != subtract) { + category = fcQNaN; + return opInvalidOp; + } + + return opOK; + + case convolve(fcNormal, fcNormal): + return opDivByZero; + } +} + +/* Add or subtract two normal numbers. */ +lostFraction +APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) +{ + integerPart carry; + lostFraction lost_fraction; + int bits; + + /* Determine if the operation on the absolute values is effectively + an addition or subtraction. */ + subtract ^= (sign ^ rhs.sign); + + /* Are we bigger exponent-wise than the RHS? */ + bits = exponent - rhs.exponent; + + /* Subtraction is more subtle than one might naively expect. */ + if(subtract) { + APFloat temp_rhs(rhs); + bool reverse; + + if(bits == 0) { + reverse = compareAbsoluteValue(temp_rhs) == cmpLessThan; + lost_fraction = lfExactlyZero; + } else if(bits > 0) { + lost_fraction = temp_rhs.shiftSignificandRight(bits - 1); + shiftSignificandLeft(1); + reverse = false; + } else if(bits < 0) { + lost_fraction = shiftSignificandRight(-bits - 1); + temp_rhs.shiftSignificandLeft(1); + reverse = true; + } + + if(reverse) { + carry = temp_rhs.subtractSignificand + (*this, lost_fraction != lfExactlyZero); + copySignificand(temp_rhs); + sign = !sign; + } else { + carry = subtractSignificand + (temp_rhs, lost_fraction != lfExactlyZero); + } + + /* Invert the lost fraction - it was on the RHS and + subtracted. */ + if(lost_fraction == lfLessThanHalf) + lost_fraction = lfMoreThanHalf; + else if(lost_fraction == lfMoreThanHalf) + lost_fraction = lfLessThanHalf; + + /* The code above is intended to ensure that no borrow is + necessary. */ + assert(!carry); + } else { + if(bits > 0) { + APFloat temp_rhs(rhs); + + lost_fraction = temp_rhs.shiftSignificandRight(bits); + carry = addSignificand(temp_rhs); + } else { + lost_fraction = shiftSignificandRight(-bits); + carry = addSignificand(rhs); + } + + /* We have a guard bit; generating a carry cannot happen. */ + assert(!carry); + } + + return lost_fraction; +} + +APFloat::opStatus +APFloat::multiplySpecials(const APFloat &rhs) +{ + switch(convolve(category, rhs.category)) { + default: + assert(0); + + case convolve(fcQNaN, fcZero): + case convolve(fcQNaN, fcNormal): + case convolve(fcQNaN, fcInfinity): + case convolve(fcQNaN, fcQNaN): + case convolve(fcZero, fcQNaN): + case convolve(fcNormal, fcQNaN): + case convolve(fcInfinity, fcQNaN): + category = fcQNaN; + return opOK; + + case convolve(fcNormal, fcInfinity): + case convolve(fcInfinity, fcNormal): + case convolve(fcInfinity, fcInfinity): + category = fcInfinity; + return opOK; + + case convolve(fcZero, fcNormal): + case convolve(fcNormal, fcZero): + case convolve(fcZero, fcZero): + category = fcZero; + return opOK; + + case convolve(fcZero, fcInfinity): + case convolve(fcInfinity, fcZero): + category = fcQNaN; + return opInvalidOp; + + case convolve(fcNormal, fcNormal): + return opOK; + } +} + +APFloat::opStatus +APFloat::divideSpecials(const APFloat &rhs) +{ + switch(convolve(category, rhs.category)) { + default: + assert(0); + + case convolve(fcQNaN, fcZero): + case convolve(fcQNaN, fcNormal): + case convolve(fcQNaN, fcInfinity): + case convolve(fcQNaN, fcQNaN): + case convolve(fcInfinity, fcZero): + case convolve(fcInfinity, fcNormal): + case convolve(fcZero, fcInfinity): + case convolve(fcZero, fcNormal): + return opOK; + + case convolve(fcZero, fcQNaN): + case convolve(fcNormal, fcQNaN): + case convolve(fcInfinity, fcQNaN): + category = fcQNaN; + return opOK; + + case convolve(fcNormal, fcInfinity): + category = fcZero; + return opOK; + + case convolve(fcNormal, fcZero): + category = fcInfinity; + return opDivByZero; + + case convolve(fcInfinity, fcInfinity): + case convolve(fcZero, fcZero): + category = fcQNaN; + return opInvalidOp; + + case convolve(fcNormal, fcNormal): + return opOK; + } +} + +/* Change sign. */ +void +APFloat::changeSign() +{ + /* Look mummy, this one's easy. */ + sign = !sign; +} + +/* Normalized addition or subtraction. */ +APFloat::opStatus +APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode, + bool subtract) +{ + opStatus fs; + + fs = addOrSubtractSpecials(rhs, subtract); + + /* This return code means it was not a simple case. */ + if(fs == opDivByZero) { + lostFraction lost_fraction; + + lost_fraction = addOrSubtractSignificand(rhs, subtract); + fs = normalize(rounding_mode, lost_fraction); + + /* Can only be zero if we lost no fraction. */ + assert(category != fcZero || lost_fraction == lfExactlyZero); + } + + /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a + positive zero unless rounding to minus infinity, except that + adding two like-signed zeroes gives that zero. */ + if(category == fcZero) { + if(rhs.category != fcZero || (sign == rhs.sign) == subtract) + sign = (rounding_mode == rmTowardNegative); + } + + return fs; +} + +/* Normalized addition. */ +APFloat::opStatus +APFloat::add(const APFloat &rhs, roundingMode rounding_mode) +{ + return addOrSubtract(rhs, rounding_mode, false); +} + +/* Normalized subtraction. */ +APFloat::opStatus +APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode) +{ + return addOrSubtract(rhs, rounding_mode, true); +} + +/* Normalized multiply. */ +APFloat::opStatus +APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) +{ + opStatus fs; + + sign ^= rhs.sign; + fs = multiplySpecials(rhs); + + if(category == fcNormal) { + lostFraction lost_fraction = multiplySignificand(rhs, 0); + fs = normalize(rounding_mode, lost_fraction); + if(lost_fraction != lfExactlyZero) + fs = (opStatus) (fs | opInexact); + } + + return fs; +} + +/* Normalized divide. */ +APFloat::opStatus +APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) +{ + opStatus fs; + + sign ^= rhs.sign; + fs = divideSpecials(rhs); + + if(category == fcNormal) { + lostFraction lost_fraction = divideSignificand(rhs); + fs = normalize(rounding_mode, lost_fraction); + if(lost_fraction != lfExactlyZero) + fs = (opStatus) (fs | opInexact); + } + + return fs; +} + +/* Normalized fused-multiply-add. */ +APFloat::opStatus +APFloat::fusedMultiplyAdd(const APFloat &multiplicand, + const APFloat &addend, + roundingMode rounding_mode) +{ + opStatus fs; + + /* Post-multiplication sign, before addition. */ + sign ^= multiplicand.sign; + + /* If and only if all arguments are normal do we need to do an + extended-precision calculation. */ + if(category == fcNormal + && multiplicand.category == fcNormal + && addend.category == fcNormal) { + lostFraction lost_fraction; + + lost_fraction = multiplySignificand(multiplicand, &addend); + fs = normalize(rounding_mode, lost_fraction); + if(lost_fraction != lfExactlyZero) + fs = (opStatus) (fs | opInexact); + + /* If two numbers add (exactly) to zero, IEEE 754 decrees it is a + positive zero unless rounding to minus infinity, except that + adding two like-signed zeroes gives that zero. */ + if(category == fcZero && sign != addend.sign) + sign = (rounding_mode == rmTowardNegative); + } else { + fs = multiplySpecials(multiplicand); + + /* FS can only be opOK or opInvalidOp. There is no more work + to do in the latter case. The IEEE-754R standard says it is + implementation-defined in this case whether, if ADDEND is a + quiet QNaN, we raise invalid op; this implementation does so. + + If we need to do the addition we can do so with normal + precision. */ + if(fs == opOK) + fs = addOrSubtract(addend, rounding_mode, false); + } + + return fs; +} + +/* Comparison requires normalized numbers. */ +APFloat::cmpResult +APFloat::compare(const APFloat &rhs) const +{ + cmpResult result; + + assert(semantics == rhs.semantics); + + switch(convolve(category, rhs.category)) { + default: + assert(0); + + case convolve(fcQNaN, fcZero): + case convolve(fcQNaN, fcNormal): + case convolve(fcQNaN, fcInfinity): + case convolve(fcQNaN, fcQNaN): + case convolve(fcZero, fcQNaN): + case convolve(fcNormal, fcQNaN): + case convolve(fcInfinity, fcQNaN): + return cmpUnordered; + + case convolve(fcInfinity, fcNormal): + case convolve(fcInfinity, fcZero): + case convolve(fcNormal, fcZero): + if(sign) + return cmpLessThan; + else + return cmpGreaterThan; + + case convolve(fcNormal, fcInfinity): + case convolve(fcZero, fcInfinity): + case convolve(fcZero, fcNormal): + if(rhs.sign) + return cmpGreaterThan; + else + return cmpLessThan; + + case convolve(fcInfinity, fcInfinity): + if(sign == rhs.sign) + return cmpEqual; + else if(sign) + return cmpLessThan; + else + return cmpGreaterThan; + + case convolve(fcZero, fcZero): + return cmpEqual; + + case convolve(fcNormal, fcNormal): + break; + } + + /* Two normal numbers. Do they have the same sign? */ + if(sign != rhs.sign) { + if(sign) + result = cmpLessThan; + else + result = cmpGreaterThan; + } else { + /* Compare absolute values; invert result if negative. */ + result = compareAbsoluteValue(rhs); + + if(sign) { + if(result == cmpLessThan) + result = cmpGreaterThan; + else if(result == cmpGreaterThan) + result = cmpLessThan; + } + } + + return result; +} + +APFloat::opStatus +APFloat::convert(const fltSemantics &toSemantics, + roundingMode rounding_mode) +{ + unsigned int newPartCount; + opStatus fs; + + newPartCount = partCountForBits(toSemantics.precision + 1); + + /* If our new form is wider, re-allocate our bit pattern into wider + storage. */ + if(newPartCount > partCount()) { + integerPart *newParts; + + newParts = new integerPart[newPartCount]; + APInt::tcSet(newParts, 0, newPartCount); + APInt::tcAssign(newParts, significandParts(), partCount()); + freeSignificand(); + significand.parts = newParts; + } + + if(category == fcNormal) { + /* Re-interpret our bit-pattern. */ + exponent += toSemantics.precision - semantics->precision; + semantics = &toSemantics; + fs = normalize(rounding_mode, lfExactlyZero); + } else { + semantics = &toSemantics; + fs = opOK; + } + + return fs; +} + +/* Convert a floating point number to an integer according to the + rounding mode. If the rounded integer value is out of range this + returns an invalid operation exception. If the rounded value is in + range but the floating point number is not the exact integer, the C + standard doesn't require an inexact exception to be raised. IEEE + 854 does require it so we do that. + + Note that for conversions to integer type the C standard requires + round-to-zero to always be used. */ +APFloat::opStatus +APFloat::convertToInteger(integerPart *parts, unsigned int width, + bool isSigned, + roundingMode rounding_mode) const +{ + lostFraction lost_fraction; + unsigned int msb, partsCount; + int bits; + + /* Handle the three special cases first. */ + if(category == fcInfinity || category == fcQNaN) + return opInvalidOp; + + partsCount = partCountForBits(width); + + if(category == fcZero) { + APInt::tcSet(parts, 0, partsCount); + return opOK; + } + + /* Shift the bit pattern so the fraction is lost. */ + APFloat tmp(*this); + + bits = (int) semantics->precision - 1 - exponent; + + if(bits > 0) { + lost_fraction = tmp.shiftSignificandRight(bits); + } else { + tmp.shiftSignificandLeft(-bits); + lost_fraction = lfExactlyZero; + } + + if(lost_fraction != lfExactlyZero + && tmp.roundAwayFromZero(rounding_mode, lost_fraction)) + tmp.incrementSignificand(); + + msb = tmp.significandMSB(); + + /* Negative numbers cannot be represented as unsigned. */ + if(!isSigned && tmp.sign && msb != -1U) + return opInvalidOp; + + /* It takes exponent + 1 bits to represent the truncated floating + point number without its sign. We lose a bit for the sign, but + the maximally negative integer is a special case. */ + if(msb + 1 > width) /* !! Not same as msb >= width !! */ + return opInvalidOp; + + if(isSigned && msb + 1 == width + && (!tmp.sign || tmp.significandLSB() != msb)) + return opInvalidOp; + + APInt::tcAssign(parts, tmp.significandParts(), partsCount); + + if(tmp.sign) + APInt::tcNegate(parts, partsCount); + + if(lost_fraction == lfExactlyZero) + return opOK; + else + return opInexact; +} + +APFloat::opStatus +APFloat::convertFromUnsignedInteger(integerPart *parts, + unsigned int partCount, + roundingMode rounding_mode) +{ + unsigned int msb, precision; + lostFraction lost_fraction; + + msb = APInt::tcMSB(parts, partCount) + 1; + precision = semantics->precision; + + category = fcNormal; + exponent = precision - 1; + + if(msb > precision) { + exponent += (msb - precision); + lost_fraction = shiftRight(parts, partCount, msb - precision); + msb = precision; + } else + lost_fraction = lfExactlyZero; + + /* Copy the bit image. */ + zeroSignificand(); + APInt::tcAssign(significandParts(), parts, partCountForBits(msb)); + + return normalize(rounding_mode, lost_fraction); +} + +APFloat::opStatus +APFloat::convertFromInteger(const integerPart *parts, + unsigned int partCount, bool isSigned, + roundingMode rounding_mode) +{ + unsigned int width; + opStatus status; + integerPart *copy; + + copy = new integerPart[partCount]; + APInt::tcAssign(copy, parts, partCount); + + width = partCount * integerPartWidth; + + sign = false; + if(isSigned && APInt::tcExtractBit(parts, width - 1)) { + sign = true; + APInt::tcNegate(copy, partCount); + } + + status = convertFromUnsignedInteger(copy, partCount, rounding_mode); + delete [] copy; + + return status; +} + +APFloat::opStatus +APFloat::convertFromHexadecimalString(const char *p, + roundingMode rounding_mode) +{ + lostFraction lost_fraction; + integerPart *significand; + unsigned int bitPos, partsCount; + const char *dot, *firstSignificantDigit; + + zeroSignificand(); + exponent = 0; + category = fcNormal; + + significand = significandParts(); + partsCount = partCount(); + bitPos = partsCount * integerPartWidth; + + /* Skip leading zeroes and any(hexa)decimal point. */ + p = skipLeadingZeroesAndAnyDot(p, &dot); + firstSignificantDigit = p; + + for(;;) { + integerPart hex_value; + + if(*p == '.') { + assert(dot == 0); + dot = p++; + } + + hex_value = hexDigitValue(*p); + if(hex_value == -1U) { + lost_fraction = lfExactlyZero; + break; + } + + p++; + + /* Store the number whilst 4-bit nibbles remain. */ + if(bitPos) { + bitPos -= 4; + hex_value <<= bitPos % integerPartWidth; + significand[bitPos / integerPartWidth] |= hex_value; + } else { + lost_fraction = trailingHexadecimalFraction(p, hex_value); + while(hexDigitValue(*p) != -1U) + p++; + break; + } + } + + /* Hex floats require an exponent but not a hexadecimal point. */ + assert(*p == 'p' || *p == 'P'); + + /* Ignore the exponent if we are zero. */ + if(p != firstSignificantDigit) { + int expAdjustment; + + /* Implicit hexadecimal point? */ + if(!dot) + dot = p; + + /* Calculate the exponent adjustment implicit in the number of + significant digits. */ + expAdjustment = dot - firstSignificantDigit; + if(expAdjustment < 0) + expAdjustment++; + expAdjustment = expAdjustment * 4 - 1; + + /* Adjust for writing the significand starting at the most + significant nibble. */ + expAdjustment += semantics->precision; + expAdjustment -= partsCount * integerPartWidth; + + /* Adjust for the given exponent. */ + exponent = totalExponent(p, expAdjustment); + } + + return normalize(rounding_mode, lost_fraction); +} + +APFloat::opStatus +APFloat::convertFromString(const char *p, roundingMode rounding_mode) +{ + /* Handle a leading minus sign. */ + if(*p == '-') + sign = 1, p++; + else + sign = 0; + + if(p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) + return convertFromHexadecimalString(p + 2, rounding_mode); + else + { + assert(0 && "Decimal to binary conversions not yet imlemented"); + abort(); + } +} Modified: llvm/trunk/lib/Support/APInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=41203&r1=41202&r2=41203&view=diff ============================================================================== --- llvm/trunk/lib/Support/APInt.cpp (original) +++ llvm/trunk/lib/Support/APInt.cpp Mon Aug 20 17:49:32 2007 @@ -2018,19 +2018,39 @@ /* Assumed by lowHalf, highHalf, partMSB and partLSB. A fairly safe and unrestricting assumption. */ -compileTimeAssert(integerPartWidth % 2 == 0); - -#define lowBitMask(bits) (~(integerPart) 0 >> (integerPartWidth - (bits))) -#define lowHalf(part) ((part) & lowBitMask(integerPartWidth / 2)) -#define highHalf(part) ((part) >> (integerPartWidth / 2)) +COMPILE_TIME_ASSERT(integerPartWidth % 2 == 0); /* Some handy functions local to this file. */ namespace { + /* Returns the integer part with the least significant BITS set. + BITS cannot be zero. */ + inline integerPart + lowBitMask(unsigned int bits) + { + assert (bits != 0 && bits <= integerPartWidth); + + return ~(integerPart) 0 >> (integerPartWidth - bits); + } + + /* Returns the value of the lower nibble of PART. */ + inline integerPart + lowHalf(integerPart part) + { + return part & lowBitMask(integerPartWidth / 2); + } + + /* Returns the value of the upper nibble of PART. */ + inline integerPart + highHalf(integerPart part) + { + return part >> (integerPartWidth / 2); + } + /* Returns the bit number of the most significant bit of a part. If the input number has no bits set -1U is returned. */ unsigned int - PartMSB(integerPart value) + partMSB(integerPart value) { unsigned int n, msb; @@ -2157,7 +2177,7 @@ --n; if (parts[n] != 0) { - msb = PartMSB(parts[n]); + msb = partMSB(parts[n]); return msb + n * integerPartWidth; } @@ -2388,11 +2408,11 @@ assert(lhs != remainder && lhs != srhs && remainder != srhs); - shiftCount = tcMSB(rhs, parts); - if (shiftCount == -1U) + shiftCount = tcMSB(rhs, parts) + 1; + if (shiftCount == 0) return true; - shiftCount = parts * integerPartWidth - shiftCount - 1; + shiftCount = parts * integerPartWidth - shiftCount; n = shiftCount / integerPartWidth; mask = (integerPart) 1 << (shiftCount % integerPartWidth); From dpatel at apple.com Mon Aug 20 18:51:19 2007 From: dpatel at apple.com (Devang Patel) Date: Mon, 20 Aug 2007 23:51:19 -0000 Subject: [llvm-commits] [llvm] r41204 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708202351.l7KNpJKW005268@zion.cs.uiuc.edu> Author: dpatel Date: Mon Aug 20 18:51:18 2007 New Revision: 41204 URL: http://llvm.org/viewvc/llvm-project?rev=41204&view=rev Log: s/ExitBlock/ExitingBlock/g Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41204&r1=41203&r2=41204&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Mon Aug 20 18:51:18 2007 @@ -94,9 +94,9 @@ /// this loop may not be eliminated. bool safeHeader(SplitInfo &SD, BasicBlock *BB); - /// If Exit block includes loop variant instructions then this + /// If Exiting block includes loop variant instructions then this /// loop may not be eliminated. - bool safeExitBlock(SplitInfo &SD, BasicBlock *BB); + bool safeExitingBlock(SplitInfo &SD, BasicBlock *BB); /// removeBlocks - Remove basic block DeadBB and all blocks dominated by DeadBB. /// This routine is used to remove split condition's dead branch, dominated by @@ -269,24 +269,24 @@ // Find loop's exit condition and associated induction variable. void LoopIndexSplit::findLoopConditionals() { - BasicBlock *ExitBlock = NULL; + BasicBlock *ExitingBlock = NULL; for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) { BasicBlock *BB = *I; if (!L->isLoopExit(BB)) continue; - if (ExitBlock) + if (ExitingBlock) return; - ExitBlock = BB; + ExitingBlock = BB; } - if (!ExitBlock) + if (!ExitingBlock) return; // If exit block's terminator is conditional branch inst then we have found // exit condition. - BranchInst *BR = dyn_cast(ExitBlock->getTerminator()); + BranchInst *BR = dyn_cast(ExitingBlock->getTerminator()); if (!BR || BR->isUnconditional()) return; @@ -411,9 +411,9 @@ if (!safeHeader(SD, Header)) return false; - // If Exit block includes loop variant instructions then this + // If Exiting block includes loop variant instructions then this // loop may not be eliminated. - if (!safeExitBlock(SD, ExitCondition->getParent())) + if (!safeExitingBlock(SD, ExitCondition->getParent())) return false; // Update CFG. @@ -531,12 +531,13 @@ return true; } -// If Exit block includes loop variant instructions then this +// If Exiting block includes loop variant instructions then this // loop may not be eliminated. This is used by processOneIterationLoop(). -bool LoopIndexSplit::safeExitBlock(SplitInfo &SD, BasicBlock *ExitBlock) { +bool LoopIndexSplit::safeExitingBlock(SplitInfo &SD, + BasicBlock *ExitingBlock) { - for (BasicBlock::iterator BI = ExitBlock->begin(), BE = ExitBlock->end(); - BI != BE; ++BI) { + for (BasicBlock::iterator BI = ExitingBlock->begin(), + BE = ExitingBlock->end(); BI != BE; ++BI) { Instruction *I = BI; // PHI Nodes are OK. @@ -576,14 +577,14 @@ continue; } - if (I == ExitBlock->getTerminator()) + if (I == ExitingBlock->getTerminator()) continue; // Otherwise we have instruction that may not be safe. return false; } - // We could not find any reason to consider ExitBlock unsafe. + // We could not find any reason to consider ExitingBlock unsafe. return true; } @@ -777,8 +778,8 @@ //[*] True loop's exit edge enters False loop. PHINode *IndVarClone = cast(ValueMap[IndVar]); - BasicBlock *ExitBlock = ExitCondition->getParent(); - BranchInst *ExitInsn = dyn_cast(ExitBlock->getTerminator()); + BasicBlock *ExitingBlock = ExitCondition->getParent(); + BranchInst *ExitInsn = dyn_cast(ExitingBlock->getTerminator()); assert (ExitInsn && "Unable to find suitable loop exit branch"); BasicBlock *ExitDest = ExitInsn->getSuccessor(1); @@ -805,36 +806,36 @@ if (PHINode *PN = dyn_cast(BI)) { PN->removeIncomingValue(Preheader); if (PN == IndVarClone) - PN->addIncoming(FLStartValue, ExitBlock); + PN->addIncoming(FLStartValue, ExitingBlock); else { PHINode *OrigPN = cast(InverseMap[PN]); - Value *V2 = OrigPN->getIncomingValueForBlock(ExitBlock); - PN->addIncoming(V2, ExitBlock); + Value *V2 = OrigPN->getIncomingValueForBlock(ExitingBlock); + PN->addIncoming(V2, ExitingBlock); } } else break; } // Update ExitDest. Now it's predecessor is False loop's exit block. - BasicBlock *ExitBlockClone = cast(ValueMap[ExitBlock]); + BasicBlock *ExitingBlockClone = cast(ValueMap[ExitingBlock]); for (BasicBlock::iterator BI = ExitDest->begin(), BE = ExitDest->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { - PN->addIncoming(ValueMap[PN->getIncomingValueForBlock(ExitBlock)], ExitBlockClone); - PN->removeIncomingValue(ExitBlock); + PN->addIncoming(ValueMap[PN->getIncomingValueForBlock(ExitingBlock)], ExitingBlockClone); + PN->removeIncomingValue(ExitingBlock); } else break; } if (DT) { - DT->changeImmediateDominator(FalseHeader, ExitBlock); - DT->changeImmediateDominator(ExitDest, cast(ValueMap[ExitBlock])); + DT->changeImmediateDominator(FalseHeader, ExitingBlock); + DT->changeImmediateDominator(ExitDest, cast(ValueMap[ExitingBlock])); } assert (!L->contains(ExitDest) && " Unable to find exit edge destination"); //[*] Split Exit Edge. - SplitEdge(ExitBlock, FalseHeader, this); + SplitEdge(ExitingBlock, FalseHeader, this); //[*] Eliminate split condition's false branch from True loop. BranchInst *BR = cast(SplitBlock->getTerminator()); From sabre at nondot.org Mon Aug 20 19:21:08 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 21 Aug 2007 00:21:08 -0000 Subject: [llvm-commits] [llvm] r41205 - /llvm/trunk/lib/VMCore/Value.cpp Message-ID: <200708210021.l7L0L8un006395@zion.cs.uiuc.edu> Author: lattner Date: Mon Aug 20 19:21:07 2007 New Revision: 41205 URL: http://llvm.org/viewvc/llvm-project?rev=41205&view=rev Log: simplify code, improve a comment. Modified: llvm/trunk/lib/VMCore/Value.cpp Modified: llvm/trunk/lib/VMCore/Value.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=41205&r1=41204&r2=41205&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Value.cpp (original) +++ llvm/trunk/lib/VMCore/Value.cpp Mon Aug 20 19:21:07 2007 @@ -276,15 +276,15 @@ while (!use_empty()) { Use &U = *UseList; // Must handle Constants specially, we cannot call replaceUsesOfWith on a - // constant! + // constant because they are uniqued. if (Constant *C = dyn_cast(U.getUser())) { - if (!isa(C)) + if (!isa(C)) { C->replaceUsesOfWithOnConstant(this, New, &U); - else - U.set(New); - } else { - U.set(New); + continue; + } } + + U.set(New); } } From dpatel at apple.com Mon Aug 20 19:31:25 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Aug 2007 00:31:25 -0000 Subject: [llvm-commits] [llvm] r41207 - in /llvm/trunk: include/llvm/Analysis/LoopInfo.h lib/Analysis/LoopInfo.cpp lib/Analysis/ScalarEvolution.cpp lib/Transforms/IPO/LoopExtractor.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LICM.cpp lib/Transforms/Scalar/LoopRotation.cpp lib/Transforms/Scalar/LoopUnswitch.cpp lib/Transforms/Utils/LCSSA.cpp lib/Transforms/Utils/LoopSimplify.cpp Message-ID: <200708210031.l7L0VP0T006695@zion.cs.uiuc.edu> Author: dpatel Date: Mon Aug 20 19:31:24 2007 New Revision: 41207 URL: http://llvm.org/viewvc/llvm-project?rev=41207&view=rev Log: Use SmallVector instead of std::vector. Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h llvm/trunk/lib/Analysis/LoopInfo.cpp llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/lib/Transforms/Scalar/LICM.cpp llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp llvm/trunk/lib/Transforms/Utils/LCSSA.cpp llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Mon Aug 20 19:31:24 2007 @@ -32,6 +32,7 @@ #include "llvm/Pass.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { @@ -111,18 +112,18 @@ /// outside of the loop. These are the blocks _inside of the current loop_ /// which branch out. The returned list is always unique. /// - void getExitingBlocks(std::vector &Blocks) const; + void getExitingBlocks(SmallVector &Blocks) const; /// getExitBlocks - Return all of the successor blocks of this loop. These /// are the blocks _outside of the current loop_ which are branched to. /// - void getExitBlocks(std::vector &Blocks) const; + void getExitBlocks(SmallVector &Blocks) const; /// getUniqueExitBlocks - Return all unique successor blocks of this loop. /// These are the blocks _outside of the current loop_ which are branched to. /// This assumes that loop is in canonical form. /// - void getUniqueExitBlocks(std::vector &ExitBlocks) const; + void getUniqueExitBlocks(SmallVector &ExitBlocks) const; /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LoopInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LoopInfo.cpp Mon Aug 20 19:31:24 2007 @@ -350,7 +350,7 @@ /// outside of the loop. These are the blocks _inside of the current loop_ /// which branch out. The returned list is always unique. /// -void Loop::getExitingBlocks(std::vector &ExitingBlocks) const { +void Loop::getExitingBlocks(SmallVector &ExitingBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. std::vector LoopBBs(block_begin(), block_end()); @@ -369,7 +369,7 @@ /// getExitBlocks - Return all of the successor blocks of this loop. These /// are the blocks _outside of the current loop_ which are branched to. /// -void Loop::getExitBlocks(std::vector &ExitBlocks) const { +void Loop::getExitBlocks(SmallVector &ExitBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. std::vector LoopBBs(block_begin(), block_end()); @@ -387,7 +387,7 @@ /// are the blocks _outside of the current loop_ which are branched to. This /// assumes that loop is in canonical form. // -void Loop::getUniqueExitBlocks(std::vector &ExitBlocks) const { +void Loop::getUniqueExitBlocks(SmallVector &ExitBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. std::vector LoopBBs(block_begin(), block_end()); Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Aug 20 19:31:24 2007 @@ -1569,7 +1569,7 @@ /// will iterate. SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) { // If the loop has a non-one exit block count, we can't analyze it. - std::vector ExitBlocks; + SmallVector ExitBlocks; L->getExitBlocks(ExitBlocks); if (ExitBlocks.size() != 1) return UnknownValue; @@ -2620,7 +2620,7 @@ cerr << "Loop " << L->getHeader()->getName() << ": "; - std::vector ExitBlocks; + SmallVector ExitBlocks; L->getExitBlocks(ExitBlocks); if (ExitBlocks.size() != 1) cerr << " "; Modified: llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/LoopExtractor.cpp Mon Aug 20 19:31:24 2007 @@ -104,7 +104,7 @@ else { // Check to see if any exits from the loop are more than just return // blocks. - std::vector ExitBlocks; + SmallVector ExitBlocks; TLL->getExitBlocks(ExitBlocks); for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) if (!isa(ExitBlocks[i]->getTerminator())) { Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Aug 20 19:31:24 2007 @@ -224,7 +224,7 @@ SCEVExpander &RW) { // Find the exit block for the loop. We can currently only handle loops with // a single exit. - std::vector ExitBlocks; + SmallVector ExitBlocks; L->getExitBlocks(ExitBlocks); if (ExitBlocks.size() != 1) return 0; BasicBlock *ExitBlock = ExitBlocks[0]; @@ -309,7 +309,7 @@ // We insert the code into the preheader of the loop if the loop contains // multiple exit blocks, or in the exit block if there is exactly one. BasicBlock *BlockToInsertInto; - std::vector ExitBlocks; + SmallVector ExitBlocks; L->getUniqueExitBlocks(ExitBlocks); if (ExitBlocks.size() == 1) BlockToInsertInto = ExitBlocks[0]; Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Mon Aug 20 19:31:24 2007 @@ -446,7 +446,7 @@ void LICM::sink(Instruction &I) { DOUT << "LICM sinking instruction: " << I; - std::vector ExitBlocks; + SmallVector ExitBlocks; CurLoop->getExitBlocks(ExitBlocks); if (isa(I)) ++NumMovedLoads; @@ -623,7 +623,7 @@ return true; // Get the exit blocks for the current loop. - std::vector ExitBlocks; + SmallVector ExitBlocks; CurLoop->getExitBlocks(ExitBlocks); // For each exit block, get the DT node and walk up the DT until the @@ -725,7 +725,7 @@ // std::set ProcessedBlocks; - std::vector ExitBlocks; + SmallVector ExitBlocks; CurLoop->getExitBlocks(ExitBlocks); for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) if (ProcessedBlocks.insert(ExitBlocks[i]).second) { Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Mon Aug 20 19:31:24 2007 @@ -157,7 +157,7 @@ // Keep it simple, and restrict loop rotation to loops with one exit only. // In future, lift this restriction and support for multiple exits if // required. - std::vector ExitBlocks; + SmallVector ExitBlocks; L->getExitBlocks(ExitBlocks); if (ExitBlocks.size() > 1) return false; Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Mon Aug 20 19:31:24 2007 @@ -622,7 +622,7 @@ // We want the loop to come after the preheader, but before the exit blocks. LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end()); - std::vector ExitBlocks; + SmallVector ExitBlocks; L->getUniqueExitBlocks(ExitBlocks); // Split all of the edges from inside the loop to their exit blocks. Update Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Mon Aug 20 19:31:24 2007 @@ -59,7 +59,7 @@ virtual bool runOnLoop(Loop *L, LPPassManager &LPM); void ProcessInstruction(Instruction* Instr, - const std::vector& exitBlocks); + const SmallVector& exitBlocks); /// This transformation requires natural loop information & requires that /// loop preheaders be inserted into the CFG. It maintains both of these, @@ -107,7 +107,6 @@ LI = &LPM.getAnalysis(); DT = &getAnalysis(); - DominanceFrontier *DF = getAnalysisToUpdate(); // Speed up queries by creating a sorted list of blocks LoopBlocks.clear(); @@ -122,9 +121,8 @@ if (AffectedValues.empty()) return false; - std::vector exitBlocks; - L->getExitBlocks(exitBlocks); - + SmallVector exitBlocks; + L->getExitBlocks(exitBlocks); // Iterate over all affected values for this loop and insert Phi nodes // for them in the appropriate exit blocks @@ -141,7 +139,7 @@ /// processInstruction - Given a live-out instruction, insert LCSSA Phi nodes, /// eliminate all out-of-loop uses. void LCSSA::ProcessInstruction(Instruction *Instr, - const std::vector& exitBlocks) { + const SmallVector& exitBlocks) { ++NumLCSSA; // We are applying the transformation // Keep track of the blocks that have the value available already. @@ -151,7 +149,7 @@ // Insert the LCSSA phi's into the exit blocks (dominated by the value), and // add them to the Phi's map. - for (std::vector::const_iterator BBI = exitBlocks.begin(), + for (SmallVector::const_iterator BBI = exitBlocks.begin(), BBE = exitBlocks.end(); BBI != BBE; ++BBI) { BasicBlock *BB = *BBI; DomTreeNode *ExitBBNode = DT->getNode(BB); Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=41207&r1=41206&r2=41207&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Mon Aug 20 19:31:24 2007 @@ -199,7 +199,7 @@ // predecessors that are inside of the loop. This check guarantees that the // loop preheader/header will dominate the exit blocks. If the exit block has // predecessors from outside of the loop, split the edge now. - std::vector ExitBlocks; + SmallVector ExitBlocks; L->getExitBlocks(ExitBlocks); SetVector ExitBlockSet(ExitBlocks.begin(), ExitBlocks.end()); From asl at math.spbu.ru Mon Aug 20 19:31:30 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 21 Aug 2007 00:31:30 -0000 Subject: [llvm-commits] [llvm] r41208 - /llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Message-ID: <200708210031.l7L0VU9v006708@zion.cs.uiuc.edu> Author: asl Date: Mon Aug 20 19:31:30 2007 New Revision: 41208 URL: http://llvm.org/viewvc/llvm-project?rev=41208&view=rev Log: Use only 1 knob to enable exceptions on Darwin :). Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=41208&r1=41207&r2=41208&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Mon Aug 20 19:31:30 2007 @@ -95,6 +95,14 @@ DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; + + // Exceptions handling + if (!Subtarget->is64Bit()) + SupportsExceptionHandling = true; + AbsoluteEHSectionOffsets = false; + DwarfEHFrameSection = + ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support"; + DwarfExceptionSection = ".section __DATA,__gcc_except_tab"; break; case X86Subtarget::isELF: From sabre at nondot.org Mon Aug 20 19:55:23 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 21 Aug 2007 00:55:23 -0000 Subject: [llvm-commits] [llvm] r41209 - /llvm/trunk/lib/VMCore/Constants.cpp Message-ID: <200708210055.l7L0tNnm007457@zion.cs.uiuc.edu> Author: lattner Date: Mon Aug 20 19:55:23 2007 New Revision: 41209 URL: http://llvm.org/viewvc/llvm-project?rev=41209&view=rev Log: Fix potentially N^2 behavior handling arrays with many of the same value which get RAUW'd. This speeds up reading the .bc file in PR1616 from 852s to 0.19s on my G5 with a debug build. Modified: llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=41209&r1=41208&r2=41209&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Mon Aug 20 19:55:23 2007 @@ -1927,14 +1927,21 @@ //===----------------------------------------------------------------------===// // replaceUsesOfWithOnConstant implementations +/// replaceUsesOfWithOnConstant - Update this constant array to change uses of +/// 'From' to be uses of 'To'. This must update the uniquing data structures +/// etc. +/// +/// Note that we intentionally replace all uses of From with To here. Consider +/// a large array that uses 'From' 1000 times. By handling this case all here, +/// ConstantArray::replaceUsesOfWithOnConstant is only invoked once, and that +/// single invocation handles all 1000 uses. Handling them one at a time would +/// work, but would be really slow because it would have to unique each updated +/// array instance. void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { assert(isa(To) && "Cannot make Constant refer to non-constant!"); Constant *ToC = cast(To); - unsigned OperandToUpdate = U-OperandList; - assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!"); - std::pair Lookup; Lookup.first.first = getType(); Lookup.second = this; @@ -1945,18 +1952,28 @@ // Fill values with the modified operands of the constant array. Also, // compute whether this turns into an all-zeros array. bool isAllZeros = false; + unsigned NumUpdated = 0; if (!ToC->isNullValue()) { - for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) - Values.push_back(cast(O->get())); + for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { + Constant *Val = cast(O->get()); + if (Val == From) { + Val = ToC; + ++NumUpdated; + } + Values.push_back(Val); + } } else { isAllZeros = true; for (Use *O = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { Constant *Val = cast(O->get()); + if (Val == From) { + Val = ToC; + ++NumUpdated; + } Values.push_back(Val); if (isAllZeros) isAllZeros = Val->isNullValue(); } } - Values[OperandToUpdate] = ToC; Constant *Replacement = 0; if (isAllZeros) { @@ -1976,8 +1993,18 @@ // in place! ArrayConstants->MoveConstantToNewSlot(this, I); - // Update to the new value. - setOperand(OperandToUpdate, ToC); + // Update to the new value. Optimize for the case when we have a single + // operand that we're changing, but handle bulk updates efficiently. + if (NumUpdated == 1) { + unsigned OperandToUpdate = U-OperandList; + assert(getOperand(OperandToUpdate) == From && + "ReplaceAllUsesWith broken!"); + setOperand(OperandToUpdate, ToC); + } else { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (getOperand(i) == From) + setOperand(i, ToC); + } return; } } From clattner at apple.com Mon Aug 20 22:43:42 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 20 Aug 2007 20:43:42 -0700 Subject: [llvm-commits] [llvm] r41207 - in /llvm/trunk: include/llvm/Analysis/LoopInfo.h lib/Analysis/LoopInfo.cpp lib/Analysis/ScalarEvolution.cpp lib/Transforms/IPO/LoopExtractor.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LICM.cpp lib/Transforms/Scalar/LoopRotation.cpp lib/Transforms/Scalar/LoopUnswitch.cpp lib/Transforms/Utils/LCSSA.cpp lib/Transforms/Utils/LoopSimplify.cpp In-Reply-To: <200708210031.l7L0VP0T006695@zion.cs.uiuc.edu> References: <200708210031.l7L0VP0T006695@zion.cs.uiuc.edu> Message-ID: > URL: http://llvm.org/viewvc/llvm-project?rev=41207&view=rev > Log: > Use SmallVector instead of std::vector. Thanks Devang, Two minor tweaks: > /// outside of the loop. These are the blocks _inside of the > current loop_ > /// which branch out. The returned list is always unique. > /// > - void getExitingBlocks(std::vector &Blocks) const; > + void getExitingBlocks(SmallVector &Blocks) const; One of the nifty but non-obvious features of smallvector is that libraries who operate on a smallvector don't have to know the size that the client declared it as. Instead of hardcoding 8 in here, just declare these as taking "SmallVectorImpl&". This will let clients decide "how small small should be". :) > +void Loop::getExitingBlocks(SmallVector > &ExitingBlocks) const { > std::vector LoopBBs(block_begin(), block_end()); > +void Loop::getExitBlocks(SmallVector &ExitBlocks) > const { > std::vector LoopBBs(block_begin(), block_end()); > +void Loop::getUniqueExitBlocks(SmallVector > &ExitBlocks) const { > std::vector LoopBBs(block_begin(), block_end()); Since you're in here, these are good candidates for (large) smallvectors also. Try making them SmallVector<, 128> for example. -Chris From baldrick at free.fr Tue Aug 21 08:47:58 2007 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Aug 2007 13:47:58 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41220 - in /llvm-gcc-4.2/trunk/gcc/ada: decl.c trans.c utils.c Message-ID: <200708211347.l7LDlwFe008028@zion.cs.uiuc.edu> Author: baldrick Date: Tue Aug 21 08:47:57 2007 New Revision: 41220 URL: http://llvm.org/viewvc/llvm-project?rev=41220&view=rev Log: Don't modify record fields in update_pointer_to. Backport of gcc 125602. Modified: llvm-gcc-4.2/trunk/gcc/ada/decl.c llvm-gcc-4.2/trunk/gcc/ada/trans.c llvm-gcc-4.2/trunk/gcc/ada/utils.c Modified: llvm-gcc-4.2/trunk/gcc/ada/decl.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/decl.c?rev=41220&r1=41219&r2=41220&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ada/decl.c (original) +++ llvm-gcc-4.2/trunk/gcc/ada/decl.c Tue Aug 21 08:47:57 2007 @@ -2983,13 +2983,14 @@ && Ekind (Etype (gnat_desig_full)) == E_Record_Type) gnat_desig_full = Etype (gnat_desig_full); +/* LLVM local begin gcc 125602 */ /* If we are pointing to an incomplete type whose completion is an - unconstrained array, make a fat pointer type instead of a pointer - to VOID. The two types in our fields will be pointers to VOID and - will be replaced in update_pointer_to. Similarly, if the type - itself is a dummy type or an unconstrained array. Also make - a dummy TYPE_OBJECT_RECORD_TYPE in case we have any thin - pointers to it. */ + unconstrained array, make a fat pointer type. The two types in our + fields will be pointers to dummy nodes and will be replaced in + update_pointer_to. Similarly, if the type itself is a dummy type or + an unconstrained array. Also make a dummy TYPE_OBJECT_RECORD_TYPE + in case we have any thin pointers to it. */ +/* LLVM local end gcc 125602 */ if ((Present (gnat_desig_full) && Is_Array_Type (gnat_desig_full) @@ -3026,6 +3027,23 @@ gnu_type = TYPE_POINTER_TO (gnu_old); if (!gnu_type) { +/* LLVM local begin gcc 125602 */ + tree gnu_template_type = make_node (ENUMERAL_TYPE); + tree gnu_ptr_template = build_pointer_type (gnu_template_type); + tree gnu_array_type = make_node (ENUMERAL_TYPE); + tree gnu_ptr_array = build_pointer_type (gnu_array_type); + + TYPE_NAME (gnu_template_type) + = concat_id_with_name (get_entity_name (gnat_desig_type), + "XUB"); + TYPE_DUMMY_P (gnu_template_type) = 1; + + TYPE_NAME (gnu_array_type) + = concat_id_with_name (get_entity_name (gnat_desig_type), + "XUA"); + TYPE_DUMMY_P (gnu_array_type) = 1; + +/* LLVM local end gcc 125602 */ gnu_type = make_node (RECORD_TYPE); SET_TYPE_UNCONSTRAINED_ARRAY (gnu_type, gnu_old); TYPE_POINTER_TO (gnu_old) = gnu_type; @@ -3035,10 +3053,13 @@ = chainon (chainon (NULL_TREE, create_field_decl (get_identifier ("P_ARRAY"), - ptr_void_type_node, gnu_type, - 0, 0, 0, 0)), +/* LLVM local begin gcc 125602 */ + gnu_ptr_array, + gnu_type, 0, 0, 0, 0)), +/* LLVM local end gcc 125602 */ create_field_decl (get_identifier ("P_BOUNDS"), - ptr_void_type_node, +/* LLVM local gcc 125602 */ + gnu_ptr_template, gnu_type, 0, 0, 0, 0)); /* Make sure we can place this into a register. */ Modified: llvm-gcc-4.2/trunk/gcc/ada/trans.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/trans.c?rev=41220&r1=41219&r2=41220&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ada/trans.c (original) +++ llvm-gcc-4.2/trunk/gcc/ada/trans.c Tue Aug 21 08:47:57 2007 @@ -4725,19 +4725,6 @@ return GS_ALL_DONE; } - return GS_UNHANDLED; - - case COMPONENT_REF: - /* We have a kludge here. If the FIELD_DECL is from a fat pointer and is - from an early dummy type, replace it with the proper FIELD_DECL. */ - if (TYPE_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) - && DECL_ORIGINAL_FIELD (TREE_OPERAND (*expr_p, 1))) - { - TREE_OPERAND (*expr_p, 1) - = DECL_ORIGINAL_FIELD (TREE_OPERAND (*expr_p, 1)); - return GS_OK; - } - /* ... fall through ... */ default: Modified: llvm-gcc-4.2/trunk/gcc/ada/utils.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/utils.c?rev=41220&r1=41219&r2=41220&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ada/utils.c (original) +++ llvm-gcc-4.2/trunk/gcc/ada/utils.c Tue Aug 21 08:47:57 2007 @@ -2630,71 +2630,69 @@ TREE_TYPE (ref1) = new_type; } +/* LLVM local begin gcc 125602 */ /* Now deal with the unconstrained array case. In this case the "pointer" - is actually a RECORD_TYPE where the types of both fields are - pointers to void. In that case, copy the field list from the - old type to the new one and update the fields' context. */ + is actually a RECORD_TYPE where both fields are pointers to dummy nodes. + Turn them into pointers to the correct types using update_pointer_to. */ +/* LLVM local end gcc 125602 */ else if (TREE_CODE (ptr) != RECORD_TYPE || !TYPE_IS_FAT_POINTER_P (ptr)) gcc_unreachable (); else { tree new_obj_rec = TYPE_OBJECT_RECORD_TYPE (new_type); - tree ptr_temp_type; +/* LLVM local begin gcc 125602 */ + tree array_field = TYPE_FIELDS (ptr); + tree bounds_field = TREE_CHAIN (TYPE_FIELDS (ptr)); + tree new_ptr = TYPE_POINTER_TO (new_type); tree new_ref; tree var; - SET_DECL_ORIGINAL_FIELD (TYPE_FIELDS (ptr), - TYPE_FIELDS (TYPE_POINTER_TO (new_type))); - SET_DECL_ORIGINAL_FIELD (TREE_CHAIN (TYPE_FIELDS (ptr)), - TREE_CHAIN (TYPE_FIELDS - (TYPE_POINTER_TO (new_type)))); - - TYPE_FIELDS (ptr) = TYPE_FIELDS (TYPE_POINTER_TO (new_type)); - DECL_CONTEXT (TYPE_FIELDS (ptr)) = ptr; - DECL_CONTEXT (TREE_CHAIN (TYPE_FIELDS (ptr))) = ptr; - - /* Rework the PLACEHOLDER_EXPR inside the reference to the - template bounds. - - ??? This is now the only use of gnat_substitute_in_type, which - is now a very "heavy" routine to do this, so it should be replaced - at some point. */ - ptr_temp_type = TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (ptr))); - new_ref = build3 (COMPONENT_REF, ptr_temp_type, - build0 (PLACEHOLDER_EXPR, ptr), - TREE_CHAIN (TYPE_FIELDS (ptr)), NULL_TREE); - + /* Make pointers to the dummy template point to the real template. */ update_pointer_to - (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))), - gnat_substitute_in_type (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))), - TREE_CHAIN (TYPE_FIELDS (ptr)), new_ref)); + (TREE_TYPE (TREE_TYPE (bounds_field)), + TREE_TYPE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_ptr))))); - for (var = TYPE_MAIN_VARIANT (ptr); var; var = TYPE_NEXT_VARIANT (var)) - { - SET_TYPE_UNCONSTRAINED_ARRAY (var, new_type); + /* The references to the template bounds present in the array type + are made through a PLACEHOLDER_EXPR of type new_ptr. Since we + are updating ptr to make it a full replacement for new_ptr as + pointer to new_type, we must rework the PLACEHOLDER_EXPR so as + to make it of type ptr. */ + new_ref = build3 (COMPONENT_REF, TREE_TYPE (bounds_field), + build0 (PLACEHOLDER_EXPR, ptr), + bounds_field, NULL_TREE); - /* This may seem a bit gross, in particular wrt DECL_CONTEXT, but - actually is in keeping with what build_qualified_type does. */ - TYPE_FIELDS (var) = TYPE_FIELDS (ptr); - } + /* Create the new array for the new PLACEHOLDER_EXPR and make + pointers to the dummy array point to it. + ??? This is now the only use of gnat_substitute_in_type, + which is a very "heavy" routine to do this, so it + should be replaced at some point. */ + update_pointer_to + (TREE_TYPE (TREE_TYPE (array_field)), + gnat_substitute_in_type (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (new_ptr))), + TREE_CHAIN (TYPE_FIELDS (new_ptr)), new_ref)); + + /* Make ptr the pointer to new_type. */ TYPE_POINTER_TO (new_type) = TYPE_REFERENCE_TO (new_type) = TREE_TYPE (new_type) = ptr; + for (var = TYPE_MAIN_VARIANT (ptr); var; var = TYPE_NEXT_VARIANT (var)) + SET_TYPE_UNCONSTRAINED_ARRAY (var, new_type); + /* Now handle updating the allocation record, what the thin pointer points to. Update all pointers from the old record into the new - one, update the types of the fields, and recompute the size. */ - + one, update the type of the array field, and recompute the size. */ update_pointer_to (TYPE_OBJECT_RECORD_TYPE (old_type), new_obj_rec); - TREE_TYPE (TYPE_FIELDS (new_obj_rec)) = TREE_TYPE (ptr_temp_type); TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec))) - = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr))); + = TREE_TYPE (TREE_TYPE (array_field)); + DECL_SIZE (TREE_CHAIN (TYPE_FIELDS (new_obj_rec))) - = TYPE_SIZE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr)))); + = TYPE_SIZE (TREE_TYPE (TREE_TYPE (array_field))); DECL_SIZE_UNIT (TREE_CHAIN (TYPE_FIELDS (new_obj_rec))) - = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (ptr)))); + = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array_field))); +/* LLVM local end gcc 125602 */ TYPE_SIZE (new_obj_rec) = size_binop (PLUS_EXPR, From baldrick at free.fr Tue Aug 21 09:06:55 2007 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Aug 2007 14:06:55 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41221 - in /llvm-gcc-4.2/trunk/gcc: ada/utils.c llvm-types.cpp llvm.h Message-ID: <200708211406.l7LE6u9p008667@zion.cs.uiuc.edu> Author: baldrick Date: Tue Aug 21 09:06:55 2007 New Revision: 41221 URL: http://llvm.org/viewvc/llvm-project?rev=41221&view=rev Log: Unlike the C front-end, the Ada f-e handles pointer resolution itself. Fortunately, the method used maps directly to LLVM's abstract type resolution. This patch implements the mapping. Modified: llvm-gcc-4.2/trunk/gcc/ada/utils.c llvm-gcc-4.2/trunk/gcc/llvm-types.cpp llvm-gcc-4.2/trunk/gcc/llvm.h Modified: llvm-gcc-4.2/trunk/gcc/ada/utils.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/utils.c?rev=41221&r1=41220&r2=41221&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ada/utils.c (original) +++ llvm-gcc-4.2/trunk/gcc/ada/utils.c Tue Aug 21 09:06:55 2007 @@ -2562,7 +2562,13 @@ : TREE_TYPE (TYPE_FIELDS (TREE_TYPE (thin_fat_ptr_type)))); return build_unc_object_type (template_type, object_type, name); } - + +/* LLVM LOCAL begin */ +#ifdef ENABLE_LLVM +#include "llvm.h" +#endif +/* LLVM LOCAL end */ + /* Update anything previously pointing to OLD_TYPE to point to NEW_TYPE. In the normal case this is just two adjustments, but we have more to do if NEW is an UNCONSTRAINED_ARRAY_TYPE. */ @@ -2704,6 +2710,12 @@ DECL_SIZE_UNIT (TREE_CHAIN (TYPE_FIELDS (new_obj_rec)))); rest_of_type_compilation (ptr, global_bindings_p ()); } + +/* LLVM LOCAL begin */ +#ifdef ENABLE_LLVM + refine_type_to (old_type, new_type); +#endif +/* LLVM LOCAL end */ } /* Convert a pointer to a constrained array into a pointer to a fat Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=41221&r1=41220&r2=41221&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Tue Aug 21 09:06:55 2007 @@ -325,6 +325,17 @@ return size_binop (PLUS_EXPR, length, size_one_node); } +/// refine_type_to - Cause all users of the opaque type old_type to switch +/// to the more concrete type new_type. +void refine_type_to(tree old_type, tree new_type) +{ + const OpaqueType *OldTy = cast_or_null(GET_TYPE_LLVM(old_type)); + if (OldTy) { + const Type *NewTy = ConvertType (new_type); + const_cast(OldTy)->refineAbstractTypeTo(NewTy); + } +} + //===----------------------------------------------------------------------===// // Abstract Type Refinement Helpers Modified: llvm-gcc-4.2/trunk/gcc/llvm.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm.h?rev=41221&r1=41220&r2=41221&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm.h Tue Aug 21 09:06:55 2007 @@ -101,6 +101,11 @@ /* llvm_asm_file_end - Finish the .s file. */ void llvm_asm_file_end(void); +/* refine_type_to - Cause all users of the opaque type old_type to switch + * to the more concrete type new_type. + */ +void refine_type_to (union tree_node*, union tree_node*); + #endif /* ENABLE_LLVM */ #endif From greened at obbligato.org Tue Aug 21 09:57:59 2007 From: greened at obbligato.org (David Greene) Date: Tue, 21 Aug 2007 14:57:59 -0000 Subject: [llvm-commits] [llvm] r41222 - /llvm/trunk/include/llvm/Support/PassNameParser.h Message-ID: <200708211457.l7LEvx7h012372@zion.cs.uiuc.edu> Author: greened Date: Tue Aug 21 09:57:58 2007 New Revision: 41222 URL: http://llvm.org/viewvc/llvm-project?rev=41222&view=rev Log: Doxygenize comments. Modified: llvm/trunk/include/llvm/Support/PassNameParser.h Modified: llvm/trunk/include/llvm/Support/PassNameParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PassNameParser.h?rev=41222&r1=41221&r2=41222&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PassNameParser.h (original) +++ llvm/trunk/include/llvm/Support/PassNameParser.h Tue Aug 21 09:57:58 2007 @@ -89,12 +89,12 @@ } }; -//===----------------------------------------------------------------------===// -// FilteredPassNameParser class - Make use of the pass registration -// mechanism to automatically add a command line argument to opt for -// each pass that satisfies a filter criteria. Filter should return -// true for passes to be registered as command-line options. -// +///===----------------------------------------------------------------------===// +/// FilteredPassNameParser class - Make use of the pass registration +/// mechanism to automatically add a command line argument to opt for +/// each pass that satisfies a filter criteria. Filter should return +/// true for passes to be registered as command-line options. +/// template class FilteredPassNameParser : public PassNameParser { private: @@ -104,22 +104,22 @@ bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); } }; -//===----------------------------------------------------------------------===// -// PassArgFilter - A filter for use with PassNameFilterParser that only -// accepts a Pass whose Arg matches certain strings. -// -// Use like this: -// -// extern const char AllowedPassArgs[] = "-anders_aa -dse"; -// -// static cl::list< -// const PassInfo*, -// bool, -// FilteredPassNameParser > > -// PassList(cl::desc("LLVM optimizations available:")); -// -// Only the -anders_aa and -dse options will be available to the user. -// +///===----------------------------------------------------------------------===// +/// PassArgFilter - A filter for use with PassNameFilterParser that only +/// accepts a Pass whose Arg matches certain strings. +/// +/// Use like this: +/// +/// extern const char AllowedPassArgs[] = "-anders_aa -dse"; +/// +/// static cl::list< +/// const PassInfo*, +/// bool, +/// FilteredPassNameParser > > +/// PassList(cl::desc("Passes available:")); +/// +/// Only the -anders_aa and -dse options will be available to the user. +/// template class PassArgFilter { public: From dpatel at apple.com Tue Aug 21 10:02:53 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Aug 2007 08:02:53 -0700 Subject: [llvm-commits] [llvm] r41207 - in /llvm/trunk: include/llvm/Analysis/LoopInfo.h lib/Analysis/LoopInfo.cpp lib/Analysis/ScalarEvolution.cpp lib/Transforms/IPO/LoopExtractor.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LICM.cpp lib/Transforms/Scalar/LoopRotation.cpp lib/Transforms/Scalar/LoopUnswitch.cpp lib/Transforms/Utils/LCSSA.cpp lib/Transforms/Utils/LoopSimplify.cpp In-Reply-To: References: <200708210031.l7L0VP0T006695@zion.cs.uiuc.edu> Message-ID: On Aug 20, 2007, at 8:43 PM, Chris Lattner wrote: >> URL: http://llvm.org/viewvc/llvm-project?rev=41207&view=rev >> Log: >> Use SmallVector instead of std::vector. > > Thanks Devang, > > Two minor tweaks: > >> /// outside of the loop. These are the blocks _inside of the >> current loop_ >> /// which branch out. The returned list is always unique. >> /// >> - void getExitingBlocks(std::vector &Blocks) const; >> + void getExitingBlocks(SmallVector &Blocks) const; > > One of the nifty but non-obvious features of smallvector is that > libraries who operate on a smallvector don't have to know the size > that the client declared it as. Instead of hardcoding 8 in here, > just declare these as taking "SmallVectorImpl&". This > will let clients decide "how small small should be". :) nifty. > >> +void Loop::getExitingBlocks(SmallVector >> &ExitingBlocks) const { >> std::vector LoopBBs(block_begin(), block_end()); > >> +void Loop::getExitBlocks(SmallVector &ExitBlocks) >> const { >> std::vector LoopBBs(block_begin(), block_end()); > >> +void Loop::getUniqueExitBlocks(SmallVector >> &ExitBlocks) const { >> std::vector LoopBBs(block_begin(), block_end()); > > Since you're in here, these are good candidates for (large) > smallvectors also. Try making them SmallVector<, 128> for example. Yes. I intended to do it as a separate check-in. - Devang From clattner at apple.com Tue Aug 21 10:26:48 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 21 Aug 2007 08:26:48 -0700 Subject: [llvm-commits] [llvm] r41207 - in /llvm/trunk: include/llvm/Analysis/LoopInfo.h lib/Analysis/LoopInfo.cpp lib/Analysis/ScalarEvolution.cpp lib/Transforms/IPO/LoopExtractor.cpp lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LICM.cpp lib/Transforms/Scalar/LoopRotation.cpp lib/Transforms/Scalar/LoopUnswitch.cpp lib/Transforms/Utils/LCSSA.cpp lib/Transforms/Utils/LoopSimplify.cpp In-Reply-To: References: <200708210031.l7L0VP0T006695@zion.cs.uiuc.edu> Message-ID: On Aug 21, 2007, at 8:02 AM, Devang Patel wrote: >> >>> +void Loop::getExitingBlocks(SmallVector >>> &ExitingBlocks) const { >>> std::vector LoopBBs(block_begin(), block_end()); >> >>> +void Loop::getExitBlocks(SmallVector &ExitBlocks) >>> const { >>> std::vector LoopBBs(block_begin(), block_end()); >> >>> +void Loop::getUniqueExitBlocks(SmallVector >>> &ExitBlocks) const { >>> std::vector LoopBBs(block_begin(), block_end()); >> >> Since you're in here, these are good candidates for (large) >> smallvectors also. Try making them SmallVector<, 128> for example. > > Yes. I intended to do it as a separate check-in. Sounds great, thanks Devang! -Chris From baldrick at free.fr Tue Aug 21 11:06:40 2007 From: baldrick at free.fr (Duncan Sands) Date: Tue, 21 Aug 2007 16:06:40 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41223 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h Message-ID: <200708211606.l7LG6eDP015750@zion.cs.uiuc.edu> Author: baldrick Date: Tue Aug 21 11:06:40 2007 New Revision: 41223 URL: http://llvm.org/viewvc/llvm-project?rev=41223&view=rev Log: Allow complex constants to be used as lvalues. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-internal.h Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41223&r1=41222&r2=41223&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Aug 21 11:06:40 2007 @@ -1008,8 +1008,9 @@ case IMAGPART_EXPR: return EmitLV_XXXXPART_EXPR(exp, 1); // Constants. - case LABEL_DECL: return TreeConstantToLLVM::EmitLV_LABEL_DECL(exp); - case STRING_CST: return LValue(TreeConstantToLLVM::EmitLV_STRING_CST(exp)); + case LABEL_DECL: return TreeConstantToLLVM::EmitLV_LABEL_DECL(exp); + case COMPLEX_CST: return LValue(TreeConstantToLLVM::EmitLV_COMPLEX_CST(exp)); + case STRING_CST: return LValue(TreeConstantToLLVM::EmitLV_STRING_CST(exp)); // Type Conversion. case VIEW_CONVERT_EXPR: return EmitLV_VIEW_CONVERT_EXPR(exp); @@ -5756,6 +5757,7 @@ case CONST_DECL: case VAR_DECL: return EmitLV_Decl(exp); case LABEL_DECL: return EmitLV_LABEL_DECL(exp); + case COMPLEX_CST: return EmitLV_COMPLEX_CST(exp); case STRING_CST: return EmitLV_STRING_CST(exp); case COMPONENT_REF: return EmitLV_COMPONENT_REF(exp); case ARRAY_RANGE_REF: @@ -5817,6 +5819,22 @@ return ConstantExpr::getIntToPtr(C, PointerType::get(Type::Int8Ty)); } +Constant *TreeConstantToLLVM::EmitLV_COMPLEX_CST(tree exp) { + Constant *Init = TreeConstantToLLVM::ConvertCOMPLEX_CST(exp); + + // Cache the constants to avoid making obvious duplicates that have to be + // folded by the optimizer. + static std::map ComplexCSTCache; + GlobalVariable *&Slot = ComplexCSTCache[Init]; + if (Slot) return Slot; + + // Create a new complex global. + Slot = new GlobalVariable(Init->getType(), true, + GlobalVariable::InternalLinkage, + Init, ".cpx", TheModule); + return Slot; +} + Constant *TreeConstantToLLVM::EmitLV_STRING_CST(tree exp) { Constant *Init = TreeConstantToLLVM::ConvertSTRING_CST(exp); Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=41223&r1=41222&r2=41223&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Tue Aug 21 11:06:40 2007 @@ -593,6 +593,7 @@ static Constant *EmitLV(tree_node *exp); static Constant *EmitLV_Decl(tree_node *exp); static Constant *EmitLV_LABEL_DECL(tree_node *exp); + static Constant *EmitLV_COMPLEX_CST(tree_node *exp); static Constant *EmitLV_STRING_CST(tree_node *exp); static Constant *EmitLV_COMPONENT_REF(tree_node *exp); static Constant *EmitLV_ARRAY_REF(tree_node *exp); From bruno.cardoso at gmail.com Tue Aug 21 11:06:45 2007 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Tue, 21 Aug 2007 16:06:45 -0000 Subject: [llvm-commits] [llvm] r41224 - /llvm/trunk/lib/Target/Mips/MipsInstrFormats.td Message-ID: <200708211606.l7LG6ktY015768@zion.cs.uiuc.edu> Author: bruno Date: Tue Aug 21 11:06:45 2007 New Revision: 41224 URL: http://llvm.org/viewvc/llvm-project?rev=41224&view=rev Log: Instruction Itinerary attribution fixed Modified: llvm/trunk/lib/Target/Mips/MipsInstrFormats.td Modified: llvm/trunk/lib/Target/Mips/MipsInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFormats.td?rev=41224&r1=41223&r2=41224&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrFormats.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrFormats.td Tue Aug 21 11:06:45 2007 @@ -39,6 +39,7 @@ let AsmString = asmstr; let Pattern = pattern; + let Itinerary = itin; } From bruno.cardoso at gmail.com Tue Aug 21 11:09:26 2007 From: bruno.cardoso at gmail.com (Bruno Cardoso Lopes) Date: Tue, 21 Aug 2007 16:09:26 -0000 Subject: [llvm-commits] [llvm] r41225 - in /llvm/trunk/lib/Target/Mips: MipsISelLowering.cpp MipsISelLowering.h Message-ID: <200708211609.l7LG9QJK015996@zion.cs.uiuc.edu> Author: bruno Date: Tue Aug 21 11:09:25 2007 New Revision: 41225 URL: http://llvm.org/viewvc/llvm-project?rev=41225&view=rev Log: InlineAsm asm support for integer registers added Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.h Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=41225&r1=41224&r2=41225&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Tue Aug 21 11:09:25 2007 @@ -20,6 +20,7 @@ #include "llvm/Function.h" #include "llvm/Intrinsics.h" #include "llvm/CallingConv.h" +#include "llvm/ADT/VectorExtras.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -551,3 +552,72 @@ return DAG.getNode(MipsISD::Ret, MVT::Other, Chain, DAG.getRegister(Mips::RA, MVT::i32)); } + +//===----------------------------------------------------------------------===// +// Mips Inline Assembly Support +//===----------------------------------------------------------------------===// + +/// getConstraintType - Given a constraint letter, return the type of +/// constraint it is for this target. +MipsTargetLowering::ConstraintType MipsTargetLowering:: +getConstraintType(const std::string &Constraint) const +{ + if (Constraint.size() == 1) { + // Mips specific constrainy + // GCC config/mips/constraints.md + // + // 'd' : An address register. Equivalent to r + // unless generating MIPS16 code. + // 'y' : Equivalent to r; retained for + // backwards compatibility. + // + switch (Constraint[0]) { + default : break; + case 'd': + case 'y': + return C_RegisterClass; + break; + } + } + return TargetLowering::getConstraintType(Constraint); +} + +std::pair MipsTargetLowering:: +getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const +{ + if (Constraint.size() == 1) { + switch (Constraint[0]) { + case 'r': + return std::make_pair(0U, Mips::CPURegsRegisterClass); + break; + } + } + return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); +} + +std::vector MipsTargetLowering:: +getRegClassForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const +{ + if (Constraint.size() != 1) + return std::vector(); + + switch (Constraint[0]) { + default : break; + case 'r': + // GCC Mips Constraint Letters + case 'd': + case 'y': + return make_vector(Mips::V0, Mips::V1, Mips::A0, + Mips::A1, Mips::A2, Mips::A3, + Mips::T0, Mips::T1, Mips::T2, + Mips::T3, Mips::T4, Mips::T5, + Mips::T6, Mips::T7, Mips::S0, + Mips::S1, Mips::S2, Mips::S3, + Mips::S4, Mips::S5, Mips::S6, + Mips::S7, Mips::T8, Mips::T9, 0); + break; + } + return std::vector(); +} Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=41225&r1=41224&r2=41225&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Tue Aug 21 11:09:25 2007 @@ -40,6 +40,7 @@ // Return Ret, + // Need to support addition with a input flag Add }; } @@ -79,6 +80,16 @@ SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG); SDOperand LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG); + // Inline asm support + ConstraintType getConstraintType(const std::string &Constraint) const; + + std::pair + getRegForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; + + std::vector + getRegClassForInlineAsmConstraint(const std::string &Constraint, + MVT::ValueType VT) const; }; } From dpatel at apple.com Tue Aug 21 11:39:43 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Aug 2007 16:39:43 -0000 Subject: [llvm-commits] [llvm] r41228 - in /llvm/trunk: include/llvm/Analysis/LoopInfo.h lib/Analysis/LoopInfo.cpp Message-ID: <200708211639.l7LGdiq6018109@zion.cs.uiuc.edu> Author: dpatel Date: Tue Aug 21 11:39:43 2007 New Revision: 41228 URL: http://llvm.org/viewvc/llvm-project?rev=41228&view=rev Log: No need to hardcode SmallVector size. Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h llvm/trunk/lib/Analysis/LoopInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=41228&r1=41227&r2=41228&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Tue Aug 21 11:39:43 2007 @@ -112,18 +112,18 @@ /// outside of the loop. These are the blocks _inside of the current loop_ /// which branch out. The returned list is always unique. /// - void getExitingBlocks(SmallVector &Blocks) const; + void getExitingBlocks(SmallVectorImpl &Blocks) const; /// getExitBlocks - Return all of the successor blocks of this loop. These /// are the blocks _outside of the current loop_ which are branched to. /// - void getExitBlocks(SmallVector &Blocks) const; + void getExitBlocks(SmallVectorImpl &Blocks) const; /// getUniqueExitBlocks - Return all unique successor blocks of this loop. /// These are the blocks _outside of the current loop_ which are branched to. /// This assumes that loop is in canonical form. /// - void getUniqueExitBlocks(SmallVector &ExitBlocks) const; + void getUniqueExitBlocks(SmallVectorImpl &ExitBlocks) const; /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=41228&r1=41227&r2=41228&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LoopInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LoopInfo.cpp Tue Aug 21 11:39:43 2007 @@ -350,7 +350,7 @@ /// outside of the loop. These are the blocks _inside of the current loop_ /// which branch out. The returned list is always unique. /// -void Loop::getExitingBlocks(SmallVector &ExitingBlocks) const { +void Loop::getExitingBlocks(SmallVectorImpl &ExitingBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. std::vector LoopBBs(block_begin(), block_end()); @@ -369,7 +369,7 @@ /// getExitBlocks - Return all of the successor blocks of this loop. These /// are the blocks _outside of the current loop_ which are branched to. /// -void Loop::getExitBlocks(SmallVector &ExitBlocks) const { +void Loop::getExitBlocks(SmallVectorImpl &ExitBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. std::vector LoopBBs(block_begin(), block_end()); @@ -387,7 +387,7 @@ /// are the blocks _outside of the current loop_ which are branched to. This /// assumes that loop is in canonical form. // -void Loop::getUniqueExitBlocks(SmallVector &ExitBlocks) const { +void Loop::getUniqueExitBlocks(SmallVectorImpl &ExitBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. std::vector LoopBBs(block_begin(), block_end()); From dpatel at apple.com Tue Aug 21 11:54:51 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Aug 2007 16:54:51 -0000 Subject: [llvm-commits] [llvm] r41230 - /llvm/trunk/lib/Analysis/LoopInfo.cpp Message-ID: <200708211654.l7LGsp1F019103@zion.cs.uiuc.edu> Author: dpatel Date: Tue Aug 21 11:54:51 2007 New Revision: 41230 URL: http://llvm.org/viewvc/llvm-project?rev=41230&view=rev Log: Use SmallVector. Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LoopInfo.cpp?rev=41230&r1=41229&r2=41230&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/LoopInfo.cpp (original) +++ llvm/trunk/lib/Analysis/LoopInfo.cpp Tue Aug 21 11:54:51 2007 @@ -353,7 +353,7 @@ void Loop::getExitingBlocks(SmallVectorImpl &ExitingBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. - std::vector LoopBBs(block_begin(), block_end()); + SmallVector LoopBBs(block_begin(), block_end()); std::sort(LoopBBs.begin(), LoopBBs.end()); for (std::vector::const_iterator BI = Blocks.begin(), @@ -372,7 +372,7 @@ void Loop::getExitBlocks(SmallVectorImpl &ExitBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. - std::vector LoopBBs(block_begin(), block_end()); + SmallVector LoopBBs(block_begin(), block_end()); std::sort(LoopBBs.begin(), LoopBBs.end()); for (std::vector::const_iterator BI = Blocks.begin(), @@ -390,7 +390,7 @@ void Loop::getUniqueExitBlocks(SmallVectorImpl &ExitBlocks) const { // Sort the blocks vector so that we can use binary search to do quick // lookups. - std::vector LoopBBs(block_begin(), block_end()); + SmallVector LoopBBs(block_begin(), block_end()); std::sort(LoopBBs.begin(), LoopBBs.end()); std::vector switchExitBlocks; From dpatel at apple.com Tue Aug 21 14:47:46 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Aug 2007 19:47:46 -0000 Subject: [llvm-commits] [llvm] r41246 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708211947.l7LJlll4027443@zion.cs.uiuc.edu> Author: dpatel Date: Tue Aug 21 14:47:46 2007 New Revision: 41246 URL: http://llvm.org/viewvc/llvm-project?rev=41246&view=rev Log: Preserve LCSSA. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41246&r1=41245&r2=41246&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Tue Aug 21 14:47:46 2007 @@ -835,7 +835,7 @@ assert (!L->contains(ExitDest) && " Unable to find exit edge destination"); //[*] Split Exit Edge. - SplitEdge(ExitingBlock, FalseHeader, this); + BasicBlock *TL_ExitBlock = SplitEdge(ExitingBlock, FalseHeader, this); //[*] Eliminate split condition's false branch from True loop. BranchInst *BR = cast(SplitBlock->getTerminator()); @@ -853,6 +853,20 @@ FBR->setUnconditionalDest(FBR->getSuccessor(1)); removeBlocks(TBB, FalseLoop, cast(FBR->getSuccessor(0))); + //[*] Preserve LCSSA + for(BasicBlock::iterator BI = FalseHeader->begin(), BE = FalseHeader->end(); + BI != BE; ++BI) { + if (PHINode *PN = dyn_cast(BI)) { + Value *V1 = PN->getIncomingValueForBlock(TL_ExitBlock); + PHINode *newPHI = new PHINode(PN->getType(), PN->getName()); + newPHI->addIncoming(V1, ExitingBlock); + TL_ExitBlock->getInstList().push_front(newPHI); + PN->removeIncomingValue(TL_ExitBlock); + PN->addIncoming(newPHI, TL_ExitBlock); + } else + break; + } + return true; } From dpatel at apple.com Tue Aug 21 16:12:02 2007 From: dpatel at apple.com (Devang Patel) Date: Tue, 21 Aug 2007 21:12:02 -0000 Subject: [llvm-commits] [llvm] r41250 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708212112.l7LLC2Qn029950@zion.cs.uiuc.edu> Author: dpatel Date: Tue Aug 21 16:12:02 2007 New Revision: 41250 URL: http://llvm.org/viewvc/llvm-project?rev=41250&view=rev Log: Rename bunch of variables. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41250&r1=41249&r2=41250&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Tue Aug 21 16:12:02 2007 @@ -705,90 +705,95 @@ } +/// splitLoop - Split current loop L in two loops using split information +/// SD. Update dominator information. Maintain LCSSA form. bool LoopIndexSplit::splitLoop(SplitInfo &SD) { - BasicBlock *Preheader = L->getLoopPreheader(); - BasicBlock *SplitBlock = SD.SplitCondition->getParent(); - BasicBlock *Latch = L->getLoopLatch(); - BasicBlock *Header = L->getHeader(); - BranchInst *SplitTerminator = cast(SplitBlock->getTerminator()); + // True loop is original loop. False loop is cloned loop. + BasicBlock *TL_Preheader = L->getLoopPreheader(); + BasicBlock *TL_SplitCondBlock = SD.SplitCondition->getParent(); + BasicBlock *TL_Latch = L->getLoopLatch(); + BasicBlock *TL_Header = L->getHeader(); + BranchInst *TL_SplitTerminator = + cast(TL_SplitCondBlock->getTerminator()); + // FIXME - Unable to handle triange loops at the moment. // In triangle loop, split condition is in header and one of the // the split destination is loop latch. If split condition is EQ // then such loops are already handle in processOneIterationLoop(). - if (Header == SplitBlock - && (Latch == SplitTerminator->getSuccessor(0) - || Latch == SplitTerminator->getSuccessor(1))) + BasicBlock *Succ0 = TL_SplitTerminator->getSuccessor(0); + BasicBlock *Succ1 = TL_SplitTerminator->getSuccessor(1); + if (TL_Header == TL_SplitCondBlock + && (TL_Latch == Succ0 || TL_Latch == Succ1)) return false; - + // If one of the split condition branch is post dominating other then loop // index split is not appropriate. - BasicBlock *Succ0 = SplitTerminator->getSuccessor(0); - BasicBlock *Succ1 = SplitTerminator->getSuccessor(1); - if (DT->dominates(Succ0, Latch) || DT->dominates(Succ1, Latch)) + if (DT->dominates(Succ0, TL_Latch) || DT->dominates(Succ1, TL_Latch)) return false; - + // If one of the split condition branch is a predecessor of the other // split condition branch head then do not split loop on this condition. - for(pred_iterator PI = pred_begin(Succ0), PE = pred_end(Succ0); PI != PE; ++PI) + for(pred_iterator PI = pred_begin(Succ0), PE = pred_end(Succ0); + PI != PE; ++PI) if (Succ1 == *PI) return false; - for(pred_iterator PI = pred_begin(Succ1), PE = pred_end(Succ1); PI != PE; ++PI) + for(pred_iterator PI = pred_begin(Succ1), PE = pred_end(Succ1); + PI != PE; ++PI) if (Succ0 == *PI) return false; - // True loop is original loop. False loop is cloned loop. - bool SignedPredicate = ExitCondition->isSignedPredicate(); //[*] Calculate True loop's new Exit Value in loop preheader. - // TLExitValue = min(SplitValue, ExitValue) + // TL_ExitValue = min(SplitValue, ExitValue) //[*] Calculate False loop's new Start Value in loop preheader. - // FLStartValue = min(SplitValue, TrueLoop.StartValue) - Value *TLExitValue = NULL; - Value *FLStartValue = NULL; + // FL_StartValue = min(SplitValue, TrueLoop.StartValue) + Value *TL_ExitValue = NULL; + Value *FL_StartValue = NULL; if (isa(SD.SplitValue)) { - TLExitValue = SD.SplitValue; - FLStartValue = SD.SplitValue; + TL_ExitValue = SD.SplitValue; + FL_StartValue = SD.SplitValue; } else { + Instruction *TL_PHTerminator = TL_Preheader->getTerminator(); Value *C1 = new ICmpInst(SignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, SD.SplitValue, ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", - Preheader->getTerminator()); - TLExitValue = new SelectInst(C1, SD.SplitValue, + "lsplit.ev", TL_PHTerminator); + TL_ExitValue = new SelectInst(C1, SD.SplitValue, ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", Preheader->getTerminator()); + "lsplit.ev", TL_PHTerminator); Value *C2 = new ICmpInst(SignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, SD.SplitValue, StartValue, "lsplit.sv", - Preheader->getTerminator()); - FLStartValue = new SelectInst(C2, SD.SplitValue, StartValue, - "lsplit.sv", Preheader->getTerminator()); + TL_PHTerminator); + FL_StartValue = new SelectInst(C2, SD.SplitValue, StartValue, + "lsplit.sv", TL_Preheader->getTerminator()); } //[*] Clone loop. Avoid true destination of split condition and // the blocks dominated by true destination. DenseMap ValueMap; Loop *FalseLoop = CloneLoop(L, LPM, LI, ValueMap, this); - BasicBlock *FalseHeader = FalseLoop->getHeader(); + BasicBlock *FL_Header = FalseLoop->getHeader(); //[*] True loop's exit edge enters False loop. - PHINode *IndVarClone = cast(ValueMap[IndVar]); - BasicBlock *ExitingBlock = ExitCondition->getParent(); - BranchInst *ExitInsn = dyn_cast(ExitingBlock->getTerminator()); - assert (ExitInsn && "Unable to find suitable loop exit branch"); - BasicBlock *ExitDest = ExitInsn->getSuccessor(1); - - if (L->contains(ExitDest)) { - ExitDest = ExitInsn->getSuccessor(0); - ExitInsn->setSuccessor(0, FalseHeader); + PHINode *FL_IndVar = cast(ValueMap[IndVar]); + BasicBlock *TL_ExitingBlock = ExitCondition->getParent(); + BranchInst *TL_ExitInsn = + dyn_cast(TL_ExitingBlock->getTerminator()); + assert (TL_ExitInsn && "Unable to find suitable loop exit branch"); + BasicBlock *TL_ExitDest = TL_ExitInsn->getSuccessor(1); + + if (L->contains(TL_ExitDest)) { + TL_ExitDest = TL_ExitInsn->getSuccessor(0); + TL_ExitInsn->setSuccessor(0, FL_Header); } else - ExitInsn->setSuccessor(1, FalseHeader); - + TL_ExitInsn->setSuccessor(1, FL_Header); + // Collect inverse map of Header PHINodes. DenseMap InverseMap; for (BasicBlock::iterator BI = L->getHeader()->begin(), @@ -799,67 +804,70 @@ } else break; } - + // Update False loop's header - for (BasicBlock::iterator BI = FalseHeader->begin(), BE = FalseHeader->end(); + for (BasicBlock::iterator BI = FL_Header->begin(), BE = FL_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { - PN->removeIncomingValue(Preheader); - if (PN == IndVarClone) - PN->addIncoming(FLStartValue, ExitingBlock); + PN->removeIncomingValue(TL_Preheader); + if (PN == FL_IndVar) + PN->addIncoming(FL_StartValue, TL_ExitingBlock); else { PHINode *OrigPN = cast(InverseMap[PN]); - Value *V2 = OrigPN->getIncomingValueForBlock(ExitingBlock); - PN->addIncoming(V2, ExitingBlock); + Value *V2 = OrigPN->getIncomingValueForBlock(TL_ExitingBlock); + PN->addIncoming(V2, TL_ExitingBlock); } } else break; } - - // Update ExitDest. Now it's predecessor is False loop's exit block. - BasicBlock *ExitingBlockClone = cast(ValueMap[ExitingBlock]); - for (BasicBlock::iterator BI = ExitDest->begin(), BE = ExitDest->end(); + + // Update TL_ExitDest. Now it's predecessor is False loop's exit block. + BasicBlock *FL_ExitingBlock = cast(ValueMap[TL_ExitingBlock]); + for (BasicBlock::iterator BI = TL_ExitDest->begin(), BE = TL_ExitDest->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { - PN->addIncoming(ValueMap[PN->getIncomingValueForBlock(ExitingBlock)], ExitingBlockClone); - PN->removeIncomingValue(ExitingBlock); + PN->addIncoming(ValueMap[PN->getIncomingValueForBlock(TL_ExitingBlock)], + FL_ExitingBlock); + PN->removeIncomingValue(TL_ExitingBlock); } else break; } if (DT) { - DT->changeImmediateDominator(FalseHeader, ExitingBlock); - DT->changeImmediateDominator(ExitDest, cast(ValueMap[ExitingBlock])); + DT->changeImmediateDominator(FL_Header, TL_ExitingBlock); + DT->changeImmediateDominator(TL_ExitDest, + cast(ValueMap[TL_ExitingBlock])); } - assert (!L->contains(ExitDest) && " Unable to find exit edge destination"); + assert (!L->contains(TL_ExitDest) && " Unable to find exit edge destination"); //[*] Split Exit Edge. - BasicBlock *TL_ExitBlock = SplitEdge(ExitingBlock, FalseHeader, this); + BasicBlock *TL_ExitBlock = SplitEdge(TL_ExitingBlock, FL_Header, this); //[*] Eliminate split condition's false branch from True loop. - BranchInst *BR = cast(SplitBlock->getTerminator()); - BasicBlock *FBB = BR->getSuccessor(1); - BR->setUnconditionalDest(BR->getSuccessor(0)); - removeBlocks(FBB, L, BR->getSuccessor(0)); + BranchInst *TL_BR = cast(TL_SplitCondBlock->getTerminator()); + BasicBlock *TL_FalseBlock = TL_BR->getSuccessor(1); + TL_BR->setUnconditionalDest(TL_BR->getSuccessor(0)); + removeBlocks(TL_FalseBlock, L, TL_BR->getSuccessor(0)); //[*] Update True loop's exit value using new exit value. - ExitCondition->setOperand(ExitValueNum, TLExitValue); + ExitCondition->setOperand(ExitValueNum, TL_ExitValue); //[*] Eliminate split condition's true branch in False loop CFG. - BasicBlock *FSplitBlock = cast(ValueMap[SplitBlock]); - BranchInst *FBR = cast(FSplitBlock->getTerminator()); - BasicBlock *TBB = FBR->getSuccessor(0); - FBR->setUnconditionalDest(FBR->getSuccessor(1)); - removeBlocks(TBB, FalseLoop, cast(FBR->getSuccessor(0))); + BasicBlock *FL_SplitCondBlock = cast(ValueMap[TL_SplitCondBlock]); + BranchInst *FL_BR = cast(FL_SplitCondBlock->getTerminator()); + BasicBlock *FL_TrueBlock = FL_BR->getSuccessor(0); + FL_BR->setUnconditionalDest(FL_BR->getSuccessor(1)); + removeBlocks(FL_TrueBlock, FalseLoop, + cast(FL_BR->getSuccessor(0))); //[*] Preserve LCSSA - for(BasicBlock::iterator BI = FalseHeader->begin(), BE = FalseHeader->end(); + for(BasicBlock::iterator BI = FL_Header->begin(), BE = FL_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { Value *V1 = PN->getIncomingValueForBlock(TL_ExitBlock); PHINode *newPHI = new PHINode(PN->getType(), PN->getName()); - newPHI->addIncoming(V1, ExitingBlock); + newPHI->addIncoming(V1, TL_ExitingBlock); TL_ExitBlock->getInstList().push_front(newPHI); PN->removeIncomingValue(TL_ExitBlock); PN->addIncoming(newPHI, TL_ExitBlock); @@ -869,4 +877,3 @@ return true; } - From asl at math.spbu.ru Tue Aug 21 17:40:45 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Tue, 21 Aug 2007 22:40:45 -0000 Subject: [llvm-commits] [llvm] r41257 - in /llvm/trunk: LICENSE.TXT runtime/GCCLibraries/ runtime/Makefile Message-ID: <200708212240.l7LMejeK000340@zion.cs.uiuc.edu> Author: asl Date: Tue Aug 21 17:40:44 2007 New Revision: 41257 URL: http://llvm.org/viewvc/llvm-project?rev=41257&view=rev Log: Dror GCCLibraries: they are obsolete since 2.0 release. This also reduces number of licenses used in LLVM. Removed: llvm/trunk/runtime/GCCLibraries/ Modified: llvm/trunk/LICENSE.TXT llvm/trunk/runtime/Makefile Modified: llvm/trunk/LICENSE.TXT URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/LICENSE.TXT?rev=41257&r1=41256&r2=41257&view=diff ============================================================================== --- llvm/trunk/LICENSE.TXT (original) +++ llvm/trunk/LICENSE.TXT Tue Aug 21 17:40:44 2007 @@ -66,4 +66,3 @@ Autoconf llvm/autoconf llvm/projects/ModuleMaker/autoconf llvm/projects/sample/autoconf -GNU Libc llvm/runtime/GCCLibraries/libc Modified: llvm/trunk/runtime/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/runtime/Makefile?rev=41257&r1=41256&r2=41257&view=diff ============================================================================== --- llvm/trunk/runtime/Makefile (original) +++ llvm/trunk/runtime/Makefile Tue Aug 21 17:40:44 2007 @@ -18,7 +18,7 @@ $(Echo) "Warning: with llvm-gcc version 4 and beyond" else ifneq ($(wildcard $(LLVMGCC)),) -PARALLEL_DIRS := GCCLibraries libdummy libprofile GC +PARALLEL_DIRS := libdummy libprofile GC else PARALLEL_DIRS := install all :: From isanbard at gmail.com Tue Aug 21 18:49:59 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Aug 2007 23:49:59 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r41259 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200708212349.l7LNnxSp002383@zion.cs.uiuc.edu> Author: void Date: Tue Aug 21 18:49:58 2007 New Revision: 41259 URL: http://llvm.org/viewvc/llvm-project?rev=41259&view=rev Log: For the llvm.c* intrinsics, we need to truncate or zero extend if we're placing the results in a larger or smaller location. Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=41259&r1=41258&r2=41259&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Tue Aug 21 18:49:58 2007 @@ -4281,13 +4281,19 @@ case BUILT_IN_CLZLL: { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::ctlz); + const Type *DestTy = ConvertType(TREE_TYPE(exp)); + if (Result->getType() != DestTy) + Result = Builder.CreateIntCast(Result, DestTy, "cast"); return true; } case BUILT_IN_CTZ: // These GCC builtins always return int. case BUILT_IN_CTZL: case BUILT_IN_CTZLL: { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); - EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::cttz); + EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::cttz); + const Type *DestTy = ConvertType(TREE_TYPE(exp)); + if (Result->getType() != DestTy) + Result = Builder.CreateIntCast(Result, DestTy, "cast"); return true; } case BUILT_IN_POPCOUNT: // These GCC builtins always return int. @@ -4295,6 +4301,9 @@ case BUILT_IN_POPCOUNTLL: { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::ctpop); + const Type *DestTy = ConvertType(TREE_TYPE(exp)); + if (Result->getType() != DestTy) + Result = Builder.CreateIntCast(Result, DestTy, "cast"); return true; } case BUILT_IN_SQRT: From isanbard at gmail.com Tue Aug 21 18:53:01 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Aug 2007 23:53:01 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41260 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200708212353.l7LNr1CX002485@zion.cs.uiuc.edu> Author: void Date: Tue Aug 21 18:53:01 2007 New Revision: 41260 URL: http://llvm.org/viewvc/llvm-project?rev=41260&view=rev Log: Forward-port of 41259: For the llvm.c* intrinsics, we need to truncate or zero extend if we're placing the results in a larger or smaller location. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41260&r1=41259&r2=41260&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Aug 21 18:53:01 2007 @@ -3849,13 +3849,19 @@ case BUILT_IN_CLZLL: { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::ctlz); + const Type *DestTy = ConvertType(TREE_TYPE(exp)); + if (Result->getType() != DestTy) + Result = Builder.CreateIntCast(Result, DestTy, "cast"); return true; } case BUILT_IN_CTZ: // These GCC builtins always return int. case BUILT_IN_CTZL: case BUILT_IN_CTZLL: { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); - EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::cttz); + EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::cttz); + const Type *DestTy = ConvertType(TREE_TYPE(exp)); + if (Result->getType() != DestTy) + Result = Builder.CreateIntCast(Result, DestTy, "cast"); return true; } case BUILT_IN_PARITYLL: @@ -3872,6 +3878,9 @@ case BUILT_IN_POPCOUNTLL: { Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::ctpop); + const Type *DestTy = ConvertType(TREE_TYPE(exp)); + if (Result->getType() != DestTy) + Result = Builder.CreateIntCast(Result, DestTy, "cast"); return true; } case BUILT_IN_SQRT: From isanbard at gmail.com Tue Aug 21 18:54:10 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Aug 2007 23:54:10 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r41261 - /llvm-gcc-4.0/tags/llvm-gcc-1200-09/ Message-ID: <200708212354.l7LNsAKq002522@zion.cs.uiuc.edu> Author: void Date: Tue Aug 21 18:54:10 2007 New Revision: 41261 URL: http://llvm.org/viewvc/llvm-project?rev=41261&view=rev Log: Creating llvm-gcc-1200-09 branch Added: llvm-gcc-4.0/tags/llvm-gcc-1200-09/ - copied from r41260, llvm-gcc-4.0/trunk/ From isanbard at gmail.com Tue Aug 21 18:54:16 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 21 Aug 2007 23:54:16 -0000 Subject: [llvm-commits] [llvm] r41262 - /llvm/tags/Apple/llvm-1200-09/ Message-ID: <200708212354.l7LNsGnF002536@zion.cs.uiuc.edu> Author: void Date: Tue Aug 21 18:54:16 2007 New Revision: 41262 URL: http://llvm.org/viewvc/llvm-project?rev=41262&view=rev Log: Creating llvm-1200-09 branch Added: llvm/tags/Apple/llvm-1200-09/ - copied from r41261, llvm/trunk/ From baldrick at free.fr Wed Aug 22 00:58:22 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 05:58:22 -0000 Subject: [llvm-commits] [llvm] r41266 - /llvm/trunk/test/CFrontend/2007-08-21-ComplexCst.c Message-ID: <200708220558.l7M5wMP1013647@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 00:58:22 2007 New Revision: 41266 URL: http://llvm.org/viewvc/llvm-project?rev=41266&view=rev Log: Test handling of complex constants as lvalues. Added: llvm/trunk/test/CFrontend/2007-08-21-ComplexCst.c Added: llvm/trunk/test/CFrontend/2007-08-21-ComplexCst.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-08-21-ComplexCst.c?rev=41266&view=auto ============================================================================== --- llvm/trunk/test/CFrontend/2007-08-21-ComplexCst.c (added) +++ llvm/trunk/test/CFrontend/2007-08-21-ComplexCst.c Wed Aug 22 00:58:22 2007 @@ -0,0 +1,3 @@ +// RUN: %llvmgcc -O2 -c %s -o /dev/null +void f(_Complex float z); +void g() { f(1.0i); } From isanbard at gmail.com Wed Aug 22 02:26:30 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 22 Aug 2007 07:26:30 -0000 Subject: [llvm-commits] [llvm] r41268 - /llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c Message-ID: <200708220726.l7M7QUIt016156@zion.cs.uiuc.edu> Author: void Date: Wed Aug 22 02:26:30 2007 New Revision: 41268 URL: http://llvm.org/viewvc/llvm-project?rev=41268&view=rev Log: Testcase for llvm.c* intrinsic failures. Added: llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c Added: llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c?rev=41268&view=auto ============================================================================== --- llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c (added) +++ llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c Wed Aug 22 02:26:30 2007 @@ -0,0 +1,6 @@ +// RUN: %llvmgcc -O2 -S -o - -emit-llvm %s | grep {llvm.cttz.i64} | count 1 +// RUN: %llvmgcc -O2 -S -o - -emit-llvm %s | not grep {lshr} + +int bork(unsigned long long x) { + return __builtin_ctzll(x); +} From baldrick at free.fr Wed Aug 22 03:47:00 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 08:47:00 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41269 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h llvm-types.cpp Message-ID: <200708220847.l7M8l08R025258@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 03:46:59 2007 New Revision: 41269 URL: http://llvm.org/viewvc/llvm-project?rev=41269&view=rev Log: TREE_OVERFLOW is no longer reliable, so just try to do something reasonable if imperfect for array types with overflowed size or length. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-internal.h llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41269&r1=41268&r2=41269&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Aug 22 03:46:59 2007 @@ -299,7 +299,6 @@ /// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer. /// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is /// true, returns whether the value is non-negative and fits in a uint64_t. -/// Always returns false for overflowed constants. bool isInt64(tree t, bool Unsigned) { if (HOST_BITS_PER_WIDE_INT == 64) return host_integerp(t, Unsigned); @@ -307,7 +306,7 @@ assert(HOST_BITS_PER_WIDE_INT == 32 && "Only 32- and 64-bit hosts supported!"); return - (TREE_CODE (t) == INTEGER_CST && !TREE_OVERFLOW (t)) + (TREE_CODE (t) == INTEGER_CST) && ((TYPE_UNSIGNED(TREE_TYPE(t)) == Unsigned) || // If the constant is signed and we want an unsigned result, check // that the value is non-negative. If the constant is unsigned and @@ -318,8 +317,8 @@ /// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If /// Unsigned is false, the value must fit in a int64_t. If Unsigned is true, -/// the value must be non-negative and fit in a uint64_t. Must not be used on -/// overflowed constants. These conditions can be checked by calling isInt64. +/// the value must be non-negative and fit in a uint64_t. These conditions +/// can be checked by calling isInt64. uint64_t getInt64(tree t, bool Unsigned) { assert(isInt64(t, Unsigned) && "invalid constant!"); return getINTEGER_CSTVal(t); Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=41269&r1=41268&r2=41269&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Wed Aug 22 03:46:59 2007 @@ -189,13 +189,12 @@ /// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer. /// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is /// true, returns whether the value is non-negative and fits in a uint64_t. -/// Always returns false for overflowed constants. bool isInt64(tree_node *t, bool Unsigned); /// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If /// Unsigned is false, the value must fit in a int64_t. If Unsigned is true, -/// the value must be non-negative and fit in a uint64_t. Must not be used on -/// overflowed constants. These conditions can be checked by calling isInt64. +/// the value must be non-negative and fit in a uint64_t. These conditions can +/// be checked by calling isInt64. uint64_t getInt64(tree_node *t, bool Unsigned); /// isPassedByInvisibleReference - Return true if the specified type should be Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=41269&r1=41268&r2=41269&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Wed Aug 22 03:46:59 2007 @@ -73,8 +73,15 @@ // Note down LLVM type for GCC tree node. static const Type * llvm_set_type(tree Tr, const Type *Ty) { + // Require gcc and LLVM types to have the same size, if the gcc type has a + // constant size that fits in 64 bits. Unfortunately we have to make an + // exception for huge arrays for which the size overflowed. assert(!TYPE_SIZE(Tr) || !Ty->isSized() || !isInt64(TYPE_SIZE(Tr), true) || getInt64(TYPE_SIZE(Tr), true) == getTargetData().getTypeSizeInBits(Ty) + // Due to TREE_OVERFLOW not always being set correctly, we sometimes + // turn a gcc array with an overflowed size into a zero length LLVM + // array. + || (isa(Ty) && !cast(Ty)->getNumElements()) && "LLVM type size doesn't match GCC type size!"); unsigned &TypeSlot = LTypesMap[Ty]; @@ -302,10 +309,11 @@ (!TYPE_SIZE(type) && isSequentialCompatible(type)) || // Arrays with constant size map to LLVM arrays. If the array has zero - // size then there can be two exotic cases: (1) the array might have zero - // length and a component type of variable size; or (2) the array could - // have variable length and a component type with zero size. In both - // cases we convert to a zero length LLVM array. + // size then there can be three exotic cases: (1) the array might have + // zero length and a component type of variable size; or (2) the array + // could have variable length and a component type with zero size; or + // (3) the array size computation overflowed, giving an apparent size of + // zero. In all cases we convert to a zero length LLVM array. (TYPE_SIZE(type) && isInt64(TYPE_SIZE(type), true)) ); } @@ -840,18 +848,28 @@ // to an unsized array of elements. NumElements = 0; } else if (!isInt64(length, true)) { - // A variable length array where the element type has size zero. Turn - // it into a zero length array of the element type. - assert(integer_zerop(TYPE_SIZE(TREE_TYPE(type))) - && "variable length array has constant size!"); + // A variable length array where the element type has size zero. + // Alternatively, the length may be negative due to overflow. + // Turn it into a zero length array of the element type. NumElements = 0; } else { // Normal array. NumElements = getInt64(length, true); } - return TypeDB.setType(type, ArrayType::get(ConvertType(TREE_TYPE(type)), - NumElements)); + const Type *Ty = ArrayType::get(ConvertType(TREE_TYPE(type)), + NumElements); + + if (NumElements && TYPE_SIZE(type) && Ty->isSized() && + getInt64(TYPE_SIZE(type), true) != + getTargetData().getTypeSizeInBits(Ty)) + // The type size and/or the array length overflowed. It would be nice + // to detect this earlier as in llvm-gcc-4.0, but unfortunately + // TREE_OVERFLOW is no longer reliable. Use a zero length array. + // This may result in wrong code, but that seems to be unavoidable. + Ty = ArrayType::get(ConvertType(TREE_TYPE(type)), 0); + + return TypeDB.setType(type, Ty); } // This handles cases like "int A[n]" which have a runtime constant From baldrick at free.fr Wed Aug 22 09:38:43 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 14:38:43 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41270 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h llvm-types.cpp Message-ID: <200708221438.l7MEchH8007057@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 09:38:42 2007 New Revision: 41270 URL: http://llvm.org/viewvc/llvm-project?rev=41270&view=rev Log: Revert the previous patch. Also, since host_integerp no longer checks TREE_OVERFLOW, check it explicitly in isInt64. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp llvm-gcc-4.2/trunk/gcc/llvm-internal.h llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41270&r1=41269&r2=41270&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Aug 22 09:38:42 2007 @@ -299,14 +299,15 @@ /// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer. /// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is /// true, returns whether the value is non-negative and fits in a uint64_t. +/// Always returns false for overflowed constants. bool isInt64(tree t, bool Unsigned) { if (HOST_BITS_PER_WIDE_INT == 64) - return host_integerp(t, Unsigned); + return !TREE_OVERFLOW (t) && host_integerp(t, Unsigned); else { assert(HOST_BITS_PER_WIDE_INT == 32 && "Only 32- and 64-bit hosts supported!"); return - (TREE_CODE (t) == INTEGER_CST) + (TREE_CODE (t) == INTEGER_CST && !TREE_OVERFLOW (t)) && ((TYPE_UNSIGNED(TREE_TYPE(t)) == Unsigned) || // If the constant is signed and we want an unsigned result, check // that the value is non-negative. If the constant is unsigned and @@ -317,8 +318,8 @@ /// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If /// Unsigned is false, the value must fit in a int64_t. If Unsigned is true, -/// the value must be non-negative and fit in a uint64_t. These conditions -/// can be checked by calling isInt64. +/// the value must be non-negative and fit in a uint64_t. Must not be used on +/// overflowed constants. These conditions can be checked by calling isInt64. uint64_t getInt64(tree t, bool Unsigned) { assert(isInt64(t, Unsigned) && "invalid constant!"); return getINTEGER_CSTVal(t); Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=41270&r1=41269&r2=41270&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Wed Aug 22 09:38:42 2007 @@ -189,12 +189,13 @@ /// isInt64 - Return true if t is an INTEGER_CST that fits in a 64 bit integer. /// If Unsigned is false, returns whether it fits in a int64_t. If Unsigned is /// true, returns whether the value is non-negative and fits in a uint64_t. +/// Always returns false for overflowed constants. bool isInt64(tree_node *t, bool Unsigned); /// getInt64 - Extract the value of an INTEGER_CST as a 64 bit integer. If /// Unsigned is false, the value must fit in a int64_t. If Unsigned is true, -/// the value must be non-negative and fit in a uint64_t. These conditions can -/// be checked by calling isInt64. +/// the value must be non-negative and fit in a uint64_t. Must not be used on +/// overflowed constants. These conditions can be checked by calling isInt64. uint64_t getInt64(tree_node *t, bool Unsigned); /// isPassedByInvisibleReference - Return true if the specified type should be Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=41270&r1=41269&r2=41270&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Wed Aug 22 09:38:42 2007 @@ -73,15 +73,8 @@ // Note down LLVM type for GCC tree node. static const Type * llvm_set_type(tree Tr, const Type *Ty) { - // Require gcc and LLVM types to have the same size, if the gcc type has a - // constant size that fits in 64 bits. Unfortunately we have to make an - // exception for huge arrays for which the size overflowed. assert(!TYPE_SIZE(Tr) || !Ty->isSized() || !isInt64(TYPE_SIZE(Tr), true) || getInt64(TYPE_SIZE(Tr), true) == getTargetData().getTypeSizeInBits(Ty) - // Due to TREE_OVERFLOW not always being set correctly, we sometimes - // turn a gcc array with an overflowed size into a zero length LLVM - // array. - || (isa(Ty) && !cast(Ty)->getNumElements()) && "LLVM type size doesn't match GCC type size!"); unsigned &TypeSlot = LTypesMap[Ty]; @@ -309,11 +302,10 @@ (!TYPE_SIZE(type) && isSequentialCompatible(type)) || // Arrays with constant size map to LLVM arrays. If the array has zero - // size then there can be three exotic cases: (1) the array might have - // zero length and a component type of variable size; or (2) the array - // could have variable length and a component type with zero size; or - // (3) the array size computation overflowed, giving an apparent size of - // zero. In all cases we convert to a zero length LLVM array. + // size then there can be two exotic cases: (1) the array might have zero + // length and a component type of variable size; or (2) the array could + // have variable length and a component type with zero size. In both + // cases we convert to a zero length LLVM array. (TYPE_SIZE(type) && isInt64(TYPE_SIZE(type), true)) ); } @@ -848,28 +840,18 @@ // to an unsized array of elements. NumElements = 0; } else if (!isInt64(length, true)) { - // A variable length array where the element type has size zero. - // Alternatively, the length may be negative due to overflow. - // Turn it into a zero length array of the element type. + // A variable length array where the element type has size zero. Turn + // it into a zero length array of the element type. + assert(integer_zerop(TYPE_SIZE(TREE_TYPE(type))) + && "variable length array has constant size!"); NumElements = 0; } else { // Normal array. NumElements = getInt64(length, true); } - const Type *Ty = ArrayType::get(ConvertType(TREE_TYPE(type)), - NumElements); - - if (NumElements && TYPE_SIZE(type) && Ty->isSized() && - getInt64(TYPE_SIZE(type), true) != - getTargetData().getTypeSizeInBits(Ty)) - // The type size and/or the array length overflowed. It would be nice - // to detect this earlier as in llvm-gcc-4.0, but unfortunately - // TREE_OVERFLOW is no longer reliable. Use a zero length array. - // This may result in wrong code, but that seems to be unavoidable. - Ty = ArrayType::get(ConvertType(TREE_TYPE(type)), 0); - - return TypeDB.setType(type, Ty); + return TypeDB.setType(type, ArrayType::get(ConvertType(TREE_TYPE(type)), + NumElements)); } // This handles cases like "int A[n]" which have a runtime constant From baldrick at free.fr Wed Aug 22 09:40:59 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 14:40:59 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41271 - /llvm-gcc-4.2/trunk/gcc/fold-const.c Message-ID: <200708221440.l7MEex1Y007217@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 09:40:59 2007 New Revision: 41271 URL: http://llvm.org/viewvc/llvm-project?rev=41271&view=rev Log: Make sure that the overflow flag is not lost. Modified: llvm-gcc-4.2/trunk/gcc/fold-const.c Modified: llvm-gcc-4.2/trunk/gcc/fold-const.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/fold-const.c?rev=41271&r1=41270&r2=41271&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/fold-const.c (original) +++ llvm-gcc-4.2/trunk/gcc/fold-const.c Wed Aug 22 09:40:59 2007 @@ -1890,12 +1890,21 @@ if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) { /* And some specific cases even faster than that. */ - if (code == PLUS_EXPR && integer_zerop (arg0)) +/* LLVM local begin */ + if (code == PLUS_EXPR && integer_zerop (arg0) + && !TREE_OVERFLOW (arg0)) +/* LLVM local end */ return arg1; else if ((code == MINUS_EXPR || code == PLUS_EXPR) - && integer_zerop (arg1)) +/* LLVM local begin */ + && integer_zerop (arg1) + && !TREE_OVERFLOW (arg1)) +/* LLVM local end */ return arg0; - else if (code == MULT_EXPR && integer_onep (arg0)) +/* LLVM local begin */ + else if (code == MULT_EXPR && integer_onep (arg0) + && !TREE_OVERFLOW (arg0)) +/* LLVM local end */ return arg1; /* Handle general case of two integer constants. */ From baldrick at free.fr Wed Aug 22 09:49:47 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 14:49:47 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41272 - /llvm-gcc-4.2/trunk/gcc/ada/trans.c Message-ID: <200708221449.l7MEnler007555@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 09:49:47 2007 New Revision: 41272 URL: http://llvm.org/viewvc/llvm-project?rev=41272&view=rev Log: Apple changes mean that ASM_EXPR now takes an extra parameter. Modified: llvm-gcc-4.2/trunk/gcc/ada/trans.c Modified: llvm-gcc-4.2/trunk/gcc/ada/trans.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/trans.c?rev=41272&r1=41271&r2=41272&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ada/trans.c (original) +++ llvm-gcc-4.2/trunk/gcc/ada/trans.c Wed Aug 22 09:49:47 2007 @@ -4003,9 +4003,12 @@ gnu_input_list = nreverse (gnu_input_list); gnu_output_list = nreverse (gnu_output_list); - gnu_result = build4 (ASM_EXPR, void_type_node, +/* LLVM local begin */ + gnu_result = build5 (ASM_EXPR, void_type_node, gnu_template, gnu_output_list, - gnu_input_list, gnu_clobber_list); + gnu_input_list, gnu_clobber_list, + NULL_TREE); +/* LLVM local end */ ASM_VOLATILE_P (gnu_result) = Is_Asm_Volatile (gnat_node); } else From baldrick at free.fr Wed Aug 22 11:56:02 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 16:56:02 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41276 - /llvm-gcc-4.2/trunk/ModuleInfo.txt Message-ID: <200708221656.l7MGu24a010930@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 11:56:02 2007 New Revision: 41276 URL: http://llvm.org/viewvc/llvm-project?rev=41276&view=rev Log: Forward port of r41041. Using a pipeline with these commands doesn't work. Fortunately, there's a workaround with the make -C option. Modified: llvm-gcc-4.2/trunk/ModuleInfo.txt Modified: llvm-gcc-4.2/trunk/ModuleInfo.txt URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/ModuleInfo.txt?rev=41276&r1=41275&r2=41276&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/ModuleInfo.txt (original) +++ llvm-gcc-4.2/trunk/ModuleInfo.txt Wed Aug 22 11:56:02 2007 @@ -1,4 +1,4 @@ DepModule: llvm BuildCmd: ./build-for-llvm-top.sh -CleanCmd: cd ../build.llvm-gcc-4.2 ; make clean -InstallCmd: cd ../build.llvm-gcc-4.2 ; make install +CleanCmd: make clean -C ../build.llvm-gcc-4.2 +InstallCmd: make install -C ../build.llvm-gcc-4.2 From baldrick at free.fr Wed Aug 22 12:00:12 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 17:00:12 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41277 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200708221700.l7MH0DaU011046@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 12:00:12 2007 New Revision: 41277 URL: http://llvm.org/viewvc/llvm-project?rev=41277&view=rev Log: Forward port of r40862. fix a regression compiling SingleSource/UnitTests/2005-05-11-Popcount-ffs-fls, introduced by chandler's recent patches. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41277&r1=41276&r2=41277&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Aug 22 12:00:12 2007 @@ -3906,11 +3906,12 @@ // the ffs, but should ignore the return type of ffs. Value *Amt = Emit(TREE_VALUE(TREE_OPERAND(exp, 1)), 0); EmitBuiltinUnaryIntOp(Amt, Result, Intrinsic::cttz); - Result = Builder.CreateAdd(Result, ConstantInt::get(Type::Int32Ty, 1), + Result = Builder.CreateAdd(Result, ConstantInt::get(Result->getType(), 1), "tmp"); Value *Cond = Builder.CreateICmpEQ(Amt, Constant::getNullValue(Amt->getType()), "tmp"); - Result = Builder.CreateSelect(Cond, Constant::getNullValue(Type::Int32Ty), + Result = Builder.CreateSelect(Cond, + Constant::getNullValue(Result->getType()), Result, "tmp"); return true; } @@ -3952,13 +3953,9 @@ // varying type. Make sure that we specify the actual type for "iAny" // by passing it as the 3rd and 4th parameters. This isn't needed for // most intrinsics, but is needed for ctpop, cttz, ctlz. - const Type* Tys[] = { - InVal->getType() - }; - Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, Id, Tys, - sizeof(Tys)/sizeof(Tys[0])), - InVal, "tmp"); - + const Type *Ty = InVal->getType(); + Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule, Id, &Ty, 1), + InVal, "tmp"); return true; } From baldrick at free.fr Wed Aug 22 12:15:11 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 17:15:11 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41278 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200708221715.l7MHFBwc011579@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 12:15:11 2007 New Revision: 41278 URL: http://llvm.org/viewvc/llvm-project?rev=41278&view=rev Log: Formatting: align FnDecl like the other parameters. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41278&r1=41277&r2=41278&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Aug 22 12:15:11 2007 @@ -542,9 +542,9 @@ } else { // Otherwise, just get the type from the function itself. FTy = TheTypeConverter->ConvertFunctionType(TREE_TYPE(FnDecl), - FnDecl, - static_chain, - CallingConv); + FnDecl, + static_chain, + CallingConv); } // If we've already seen this function and created a prototype, and if the From alenhar2 at cs.uiuc.edu Wed Aug 22 12:22:11 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 22 Aug 2007 17:22:11 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r41279 - /llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Message-ID: <200708221722.l7MHMB9o011938@zion.cs.uiuc.edu> Author: alenhar2 Date: Wed Aug 22 12:22:11 2007 New Revision: 41279 URL: http://llvm.org/viewvc/llvm-project?rev=41279&view=rev Log: fix PR1586 Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp?rev=41279&r1=41278&r2=41279&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Wed Aug 22 12:22:11 2007 @@ -483,8 +483,10 @@ const Type *SBP = PointerType::get(Type::Int8Ty); ArrayType *AT = ArrayType::get(SBP, AttributeUsedGlobals.size()); Constant *Init = ConstantArray::get(AT, AttributeUsedGlobals); - new GlobalVariable(AT, false, GlobalValue::AppendingLinkage, Init, + GlobalValue* gv = new GlobalVariable(AT, false, + GlobalValue::AppendingLinkage, Init, "llvm.used", TheModule); + gv->setSection("llvm.metadata"); AttributeUsedGlobals.clear(); } From dpatel at apple.com Wed Aug 22 13:07:47 2007 From: dpatel at apple.com (Devang Patel) Date: Wed, 22 Aug 2007 18:07:47 -0000 Subject: [llvm-commits] [llvm] r41280 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708221807.l7MI7l08014137@zion.cs.uiuc.edu> Author: dpatel Date: Wed Aug 22 13:07:47 2007 New Revision: 41280 URL: http://llvm.org/viewvc/llvm-project?rev=41280&view=rev Log: Fix thinko. Starting value of second loop's induction variable can not be lower then starting value of original loop's induction variable. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41280&r1=41279&r2=41280&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Wed Aug 22 13:07:47 2007 @@ -748,7 +748,7 @@ //[*] Calculate True loop's new Exit Value in loop preheader. // TL_ExitValue = min(SplitValue, ExitValue) //[*] Calculate False loop's new Start Value in loop preheader. - // FL_StartValue = min(SplitValue, TrueLoop.StartValue) + // FL_StartValue = max(SplitValue, TrueLoop.StartValue) Value *TL_ExitValue = NULL; Value *FL_StartValue = NULL; if (isa(SD.SplitValue)) { @@ -770,8 +770,8 @@ ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, SD.SplitValue, StartValue, "lsplit.sv", TL_PHTerminator); - FL_StartValue = new SelectInst(C2, SD.SplitValue, StartValue, - "lsplit.sv", TL_Preheader->getTerminator()); + FL_StartValue = new SelectInst(C2, StartValue, SD.SplitValue, + "lsplit.sv", TL_PHTerminator); } //[*] Clone loop. Avoid true destination of split condition and From dpatel at apple.com Wed Aug 22 13:27:01 2007 From: dpatel at apple.com (Devang Patel) Date: Wed, 22 Aug 2007 18:27:01 -0000 Subject: [llvm-commits] [llvm] r41282 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708221827.l7MIR1Gi015314@zion.cs.uiuc.edu> Author: dpatel Date: Wed Aug 22 13:27:01 2007 New Revision: 41282 URL: http://llvm.org/viewvc/llvm-project?rev=41282&view=rev Log: Refactor loop condition check in a separate function. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41282&r1=41281&r2=41282&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Wed Aug 22 13:27:01 2007 @@ -105,6 +105,13 @@ /// Find cost of spliting loop L. unsigned findSplitCost(Loop *L, SplitInfo &SD); + + /// safeSplitCondition - Return true if it is possible to + /// split loop using given split condition. + bool safeSplitCondition(SplitInfo &SD); + + /// splitLoop - Split current loop L in two loops using split information + /// SD. Update dominator information. Maintain LCSSA form. bool splitLoop(SplitInfo &SD); void initialize() { @@ -705,32 +712,28 @@ } -/// splitLoop - Split current loop L in two loops using split information -/// SD. Update dominator information. Maintain LCSSA form. -bool LoopIndexSplit::splitLoop(SplitInfo &SD) { - - // True loop is original loop. False loop is cloned loop. +/// safeSplitCondition - Return true if it is possible to +/// split loop using given split condition. +bool LoopIndexSplit::safeSplitCondition(SplitInfo &SD) { - BasicBlock *TL_Preheader = L->getLoopPreheader(); - BasicBlock *TL_SplitCondBlock = SD.SplitCondition->getParent(); - BasicBlock *TL_Latch = L->getLoopLatch(); - BasicBlock *TL_Header = L->getHeader(); - BranchInst *TL_SplitTerminator = - cast(TL_SplitCondBlock->getTerminator()); + BasicBlock *SplitCondBlock = SD.SplitCondition->getParent(); - // FIXME - Unable to handle triange loops at the moment. + // Unable to handle triange loops at the moment. // In triangle loop, split condition is in header and one of the // the split destination is loop latch. If split condition is EQ // then such loops are already handle in processOneIterationLoop(). - BasicBlock *Succ0 = TL_SplitTerminator->getSuccessor(0); - BasicBlock *Succ1 = TL_SplitTerminator->getSuccessor(1); - if (TL_Header == TL_SplitCondBlock - && (TL_Latch == Succ0 || TL_Latch == Succ1)) + BasicBlock *Latch = L->getLoopLatch(); + BranchInst *SplitTerminator = + cast(SplitCondBlock->getTerminator()); + BasicBlock *Succ0 = SplitTerminator->getSuccessor(0); + BasicBlock *Succ1 = SplitTerminator->getSuccessor(1); + if (L->getHeader() == SplitCondBlock + && (Latch == Succ0 || Latch == Succ1)) return false; // If one of the split condition branch is post dominating other then loop // index split is not appropriate. - if (DT->dominates(Succ0, TL_Latch) || DT->dominates(Succ1, TL_Latch)) + if (DT->dominates(Succ0, Latch) || DT->dominates(Succ1, Latch)) return false; // If one of the split condition branch is a predecessor of the other @@ -744,6 +747,20 @@ if (Succ0 == *PI) return false; + return true; +} + +/// splitLoop - Split current loop L in two loops using split information +/// SD. Update dominator information. Maintain LCSSA form. +bool LoopIndexSplit::splitLoop(SplitInfo &SD) { + + if (!safeSplitCondition(SD)) + return false; + + // True loop is original loop. False loop is cloned loop. + BasicBlock *TL_SplitCondBlock = SD.SplitCondition->getParent(); + BasicBlock *TL_Preheader = L->getLoopPreheader(); + bool SignedPredicate = ExitCondition->isSignedPredicate(); //[*] Calculate True loop's new Exit Value in loop preheader. // TL_ExitValue = min(SplitValue, ExitValue) From isanbard at gmail.com Wed Aug 22 13:44:05 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 22 Aug 2007 18:44:05 -0000 Subject: [llvm-commits] [llvm] r41284 - /llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Message-ID: <200708221844.l7MIi5SE016688@zion.cs.uiuc.edu> Author: void Date: Wed Aug 22 13:44:05 2007 New Revision: 41284 URL: http://llvm.org/viewvc/llvm-project?rev=41284&view=rev Log: Add the PCSymbol for Darwin x86 platforms. Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=41284&r1=41283&r2=41284&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Wed Aug 22 13:44:05 2007 @@ -71,6 +71,7 @@ InlineAsmStart = "# InlineAsm Start"; InlineAsmEnd = "# InlineAsm End"; SetDirective = "\t.set"; + PCSymbol = "."; UsedDirective = "\t.no_dead_strip\t"; WeakRefDirective = "\t.weak_reference\t"; HiddenDirective = "\t.private_extern\t"; From baldrick at free.fr Wed Aug 22 14:15:04 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 19:15:04 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41285 - /llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Message-ID: <200708221915.l7MJF4u2018481@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 14:15:04 2007 New Revision: 41285 URL: http://llvm.org/viewvc/llvm-project?rev=41285&view=rev Log: Forward port of r40544. Unbreak Apple style build: createDeadStoreEliminationPass must be linked in until it's completely removed. Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp?rev=41285&r1=41284&r2=41285&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-linker-hack.cpp Wed Aug 22 14:15:04 2007 @@ -77,6 +77,7 @@ llvm::createDeadArgEliminationPass(); llvm::createLoadValueNumberingPass(); llvm::createTailCallEliminationPass(); + llvm::createDeadStoreEliminationPass(); llvm::createIPConstantPropagationPass(); llvm::createStripDeadPrototypesPass(); } From clattner at apple.com Wed Aug 22 14:17:23 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 22 Aug 2007 12:17:23 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r41271 - /llvm-gcc-4.2/trunk/gcc/fold-const.c In-Reply-To: <200708221440.l7MEex1Y007217@zion.cs.uiuc.edu> References: <200708221440.l7MEex1Y007217@zion.cs.uiuc.edu> Message-ID: On Aug 22, 2007, at 7:40 AM, Duncan Sands wrote: > > URL: http://llvm.org/viewvc/llvm-project?rev=41271&view=rev > Log: > Make sure that the overflow flag is not lost. Ick, is this hack to fold-const really appropriate? -Chris From baldrick at free.fr Wed Aug 22 14:18:45 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 21:18:45 +0200 Subject: [llvm-commits] [llvm-gcc-4.0] r41279 - /llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp In-Reply-To: <200708221722.l7MHMB9o011938@zion.cs.uiuc.edu> References: <200708221722.l7MHMB9o011938@zion.cs.uiuc.edu> Message-ID: <200708222118.46730.baldrick@free.fr> > fix PR1586 > > Modified: > llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Please also apply to llvm-gcc-4.2. Thanks, Duncan. From clattner at apple.com Wed Aug 22 14:19:15 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 22 Aug 2007 12:19:15 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r41279 - /llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp In-Reply-To: <200708221722.l7MHMB9o011938@zion.cs.uiuc.edu> References: <200708221722.l7MHMB9o011938@zion.cs.uiuc.edu> Message-ID: <1367AA4A-F4DD-400A-9EAA-17790E917ED4@apple.com> On Aug 22, 2007, at 10:22 AM, Andrew Lenharth wrote: > fix PR1586 This breaks llvm.used due to this code in AsmPrinter: bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { // Ignore debug and non-emitted data. if (GV->getSection() == "llvm.metadata") return true; if (!GV->hasAppendingLinkage()) return false; assert(GV->hasInitializer() && "Not a special LLVM global!"); if (GV->getName() == "llvm.used") { if (TAI->getUsedDirective() != 0) // No need to emit this at all. EmitLLVMUsedList(GV->getInitializer()); return true; } Please revert the patch or fix it, thanks! -Chris > > Modified: > llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp > > Modified: llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/ > llvm-backend.cpp?rev=41279&r1=41278&r2=41279&view=diff > > ====================================================================== > ======== > --- llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp (original) > +++ llvm-gcc-4.0/trunk/gcc/llvm-backend.cpp Wed Aug 22 12:22:11 2007 > @@ -483,8 +483,10 @@ > const Type *SBP = PointerType::get(Type::Int8Ty); > ArrayType *AT = ArrayType::get(SBP, AttributeUsedGlobals.size()); > Constant *Init = ConstantArray::get(AT, AttributeUsedGlobals); > - new GlobalVariable(AT, false, GlobalValue::AppendingLinkage, > Init, > + GlobalValue* gv = new GlobalVariable(AT, false, > + GlobalValue::AppendingLinkage, Init, > "llvm.used", TheModule); > + gv->setSection("llvm.metadata"); > AttributeUsedGlobals.clear(); > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From alenhar2 at cs.uiuc.edu Wed Aug 22 14:33:11 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 22 Aug 2007 19:33:11 -0000 Subject: [llvm-commits] [llvm] r41286 - /llvm/trunk/lib/CodeGen/AsmPrinter.cpp Message-ID: <200708221933.l7MJXBs6019270@zion.cs.uiuc.edu> Author: alenhar2 Date: Wed Aug 22 14:33:11 2007 New Revision: 41286 URL: http://llvm.org/viewvc/llvm-project?rev=41286&view=rev Log: move this check. ppc outputs .no_dead_strip properly Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter.cpp?rev=41286&r1=41285&r2=41286&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Wed Aug 22 14:33:11 2007 @@ -314,6 +314,12 @@ /// special global used by LLVM. If so, emit it and return true, otherwise /// do nothing and return false. bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { + if (GV->getName() == "llvm.used") { + if (TAI->getUsedDirective() != 0) // No need to emit this at all. + EmitLLVMUsedList(GV->getInitializer()); + return true; + } + // Ignore debug and non-emitted data. if (GV->getSection() == "llvm.metadata") return true; @@ -321,12 +327,6 @@ assert(GV->hasInitializer() && "Not a special LLVM global!"); - if (GV->getName() == "llvm.used") { - if (TAI->getUsedDirective() != 0) // No need to emit this at all. - EmitLLVMUsedList(GV->getInitializer()); - return true; - } - const TargetData *TD = TM.getTargetData(); unsigned Align = Log2_32(TD->getPointerPrefAlignment()); if (GV->getName() == "llvm.global_ctors" && GV->use_empty()) { From dpatel at apple.com Wed Aug 22 14:33:29 2007 From: dpatel at apple.com (Devang Patel) Date: Wed, 22 Aug 2007 19:33:29 -0000 Subject: [llvm-commits] [llvm] r41287 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708221933.l7MJXUpU019301@zion.cs.uiuc.edu> Author: dpatel Date: Wed Aug 22 14:33:29 2007 New Revision: 41287 URL: http://llvm.org/viewvc/llvm-project?rev=41287&view=rev Log: Cosmetic change "True Loop" and "False Loop" naming terminology to refer two loops after loop cloning is confusing. Instead just use A_Loop and B_Loop. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41287&r1=41286&r2=41287&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Wed Aug 22 14:33:29 2007 @@ -757,60 +757,73 @@ if (!safeSplitCondition(SD)) return false; - // True loop is original loop. False loop is cloned loop. - BasicBlock *TL_SplitCondBlock = SD.SplitCondition->getParent(); - BasicBlock *TL_Preheader = L->getLoopPreheader(); - - bool SignedPredicate = ExitCondition->isSignedPredicate(); - //[*] Calculate True loop's new Exit Value in loop preheader. - // TL_ExitValue = min(SplitValue, ExitValue) - //[*] Calculate False loop's new Start Value in loop preheader. - // FL_StartValue = max(SplitValue, TrueLoop.StartValue) - Value *TL_ExitValue = NULL; - Value *FL_StartValue = NULL; + // After loop is cloned there are two loops. + // + // First loop, referred as ALoop, executes first part of loop's iteration + // space split. Second loop, referred as BLoop, executes remaining + // part of loop's iteration space. + // + // ALoop's exit edge enters BLoop's header through a forwarding block which + // acts as a BLoop's preheader. + + //[*] Calculate ALoop induction variable's new exiting value and + // BLoop induction variable's new starting value. Calculuate these + // values in original loop's preheader. + // A_ExitValue = min(SplitValue, OrignalLoopExitValue) + // B_StartValue = max(SplitValue, OriginalLoopStartValue) + Value *A_ExitValue = NULL; + Value *B_StartValue = NULL; if (isa(SD.SplitValue)) { - TL_ExitValue = SD.SplitValue; - FL_StartValue = SD.SplitValue; + A_ExitValue = SD.SplitValue; + B_StartValue = SD.SplitValue; } else { - Instruction *TL_PHTerminator = TL_Preheader->getTerminator(); + BasicBlock *Preheader = L->getLoopPreheader(); + Instruction *PHTerminator = Preheader->getTerminator(); + bool SignedPredicate = ExitCondition->isSignedPredicate(); Value *C1 = new ICmpInst(SignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, SD.SplitValue, ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", TL_PHTerminator); - TL_ExitValue = new SelectInst(C1, SD.SplitValue, + "lsplit.ev", PHTerminator); + A_ExitValue = new SelectInst(C1, SD.SplitValue, ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", TL_PHTerminator); + "lsplit.ev", PHTerminator); Value *C2 = new ICmpInst(SignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, SD.SplitValue, StartValue, "lsplit.sv", - TL_PHTerminator); - FL_StartValue = new SelectInst(C2, StartValue, SD.SplitValue, - "lsplit.sv", TL_PHTerminator); + PHTerminator); + B_StartValue = new SelectInst(C2, StartValue, SD.SplitValue, + "lsplit.sv", PHTerminator); } - //[*] Clone loop. Avoid true destination of split condition and - // the blocks dominated by true destination. + //[*] Clone loop. DenseMap ValueMap; - Loop *FalseLoop = CloneLoop(L, LPM, LI, ValueMap, this); - BasicBlock *FL_Header = FalseLoop->getHeader(); + Loop *BLoop = CloneLoop(L, LPM, LI, ValueMap, this); + BasicBlock *B_Header = BLoop->getHeader(); - //[*] True loop's exit edge enters False loop. - PHINode *FL_IndVar = cast(ValueMap[IndVar]); - BasicBlock *TL_ExitingBlock = ExitCondition->getParent(); - BranchInst *TL_ExitInsn = - dyn_cast(TL_ExitingBlock->getTerminator()); - assert (TL_ExitInsn && "Unable to find suitable loop exit branch"); - BasicBlock *TL_ExitDest = TL_ExitInsn->getSuccessor(1); - - if (L->contains(TL_ExitDest)) { - TL_ExitDest = TL_ExitInsn->getSuccessor(0); - TL_ExitInsn->setSuccessor(0, FL_Header); + //[*] ALoop's exiting edge BLoop's header. + // ALoop's original exit block becomes BLoop's exit block. + PHINode *B_IndVar = cast(ValueMap[IndVar]); + BasicBlock *A_ExitingBlock = ExitCondition->getParent(); + BranchInst *A_ExitInsn = + dyn_cast(A_ExitingBlock->getTerminator()); + assert (A_ExitInsn && "Unable to find suitable loop exit branch"); + BasicBlock *B_ExitBlock = A_ExitInsn->getSuccessor(1); + if (L->contains(B_ExitBlock)) { + B_ExitBlock = A_ExitInsn->getSuccessor(0); + A_ExitInsn->setSuccessor(0, B_Header); } else - TL_ExitInsn->setSuccessor(1, FL_Header); + A_ExitInsn->setSuccessor(1, B_Header); + + //[*] Update ALoop's exit value using new exit value. + ExitCondition->setOperand(ExitValueNum, A_ExitValue); + // [*] Update BLoop's header phi nodes. Remove incoming PHINode's from + // original loop's preheader. Add incoming PHINode values from + // ALoop's exiting block. Update BLoop header's domiantor info. + // Collect inverse map of Header PHINodes. DenseMap InverseMap; for (BasicBlock::iterator BI = L->getHeader()->begin(), @@ -821,76 +834,81 @@ } else break; } - - // Update False loop's header - for (BasicBlock::iterator BI = FL_Header->begin(), BE = FL_Header->end(); + BasicBlock *Preheader = L->getLoopPreheader(); + for (BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { - PN->removeIncomingValue(TL_Preheader); - if (PN == FL_IndVar) - PN->addIncoming(FL_StartValue, TL_ExitingBlock); + // Remove incoming value from original preheader. + PN->removeIncomingValue(Preheader); + + // Add incoming value from A_ExitingBlock. + if (PN == B_IndVar) + PN->addIncoming(B_StartValue, A_ExitingBlock); else { PHINode *OrigPN = cast(InverseMap[PN]); - Value *V2 = OrigPN->getIncomingValueForBlock(TL_ExitingBlock); - PN->addIncoming(V2, TL_ExitingBlock); + Value *V2 = OrigPN->getIncomingValueForBlock(A_ExitingBlock); + PN->addIncoming(V2, A_ExitingBlock); } } else break; } + DT->changeImmediateDominator(B_Header, A_ExitingBlock); + DF->changeImmediateDominator(B_Header, A_ExitingBlock, DT); - // Update TL_ExitDest. Now it's predecessor is False loop's exit block. - BasicBlock *FL_ExitingBlock = cast(ValueMap[TL_ExitingBlock]); - for (BasicBlock::iterator BI = TL_ExitDest->begin(), BE = TL_ExitDest->end(); + // [*] Update BLoop's exit block. Its new predecessor is BLoop's exit + // block. Remove incoming PHINode values from ALoop's exiting block. + // Add new incoming values from BLoop's incoming exiting value. + // Update BLoop exit block's dominator info.. + BasicBlock *B_ExitingBlock = cast(ValueMap[A_ExitingBlock]); + for (BasicBlock::iterator BI = B_ExitBlock->begin(), BE = B_ExitBlock->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { - PN->addIncoming(ValueMap[PN->getIncomingValueForBlock(TL_ExitingBlock)], - FL_ExitingBlock); - PN->removeIncomingValue(TL_ExitingBlock); + PN->addIncoming(ValueMap[PN->getIncomingValueForBlock(A_ExitingBlock)], + B_ExitingBlock); + PN->removeIncomingValue(A_ExitingBlock); } else break; } - if (DT) { - DT->changeImmediateDominator(FL_Header, TL_ExitingBlock); - DT->changeImmediateDominator(TL_ExitDest, - cast(ValueMap[TL_ExitingBlock])); - } - - assert (!L->contains(TL_ExitDest) && " Unable to find exit edge destination"); - - //[*] Split Exit Edge. - BasicBlock *TL_ExitBlock = SplitEdge(TL_ExitingBlock, FL_Header, this); - - //[*] Eliminate split condition's false branch from True loop. - BranchInst *TL_BR = cast(TL_SplitCondBlock->getTerminator()); - BasicBlock *TL_FalseBlock = TL_BR->getSuccessor(1); - TL_BR->setUnconditionalDest(TL_BR->getSuccessor(0)); - removeBlocks(TL_FalseBlock, L, TL_BR->getSuccessor(0)); - - //[*] Update True loop's exit value using new exit value. - ExitCondition->setOperand(ExitValueNum, TL_ExitValue); - - //[*] Eliminate split condition's true branch in False loop CFG. - BasicBlock *FL_SplitCondBlock = cast(ValueMap[TL_SplitCondBlock]); - BranchInst *FL_BR = cast(FL_SplitCondBlock->getTerminator()); - BasicBlock *FL_TrueBlock = FL_BR->getSuccessor(0); - FL_BR->setUnconditionalDest(FL_BR->getSuccessor(1)); - removeBlocks(FL_TrueBlock, FalseLoop, - cast(FL_BR->getSuccessor(0))); + DT->changeImmediateDominator(B_ExitBlock, B_ExitingBlock); + DF->changeImmediateDominator(B_ExitBlock, B_ExitingBlock, DT); - //[*] Preserve LCSSA - for(BasicBlock::iterator BI = FL_Header->begin(), BE = FL_Header->end(); + //[*] Split ALoop's exit edge. This creates a new block which + // serves two purposes. First one is to hold PHINode defnitions + // to ensure that ALoop's LCSSA form. Second use it to act + // as a preheader for BLoop. + BasicBlock *A_ExitBlock = SplitEdge(A_ExitingBlock, B_Header, this); + + //[*] Preserve ALoop's LCSSA form. Create new forwarding PHINodes + // in A_ExitBlock to redefine outgoing PHI definitions from ALoop. + for(BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { - Value *V1 = PN->getIncomingValueForBlock(TL_ExitBlock); + Value *V1 = PN->getIncomingValueForBlock(A_ExitBlock); PHINode *newPHI = new PHINode(PN->getType(), PN->getName()); - newPHI->addIncoming(V1, TL_ExitingBlock); - TL_ExitBlock->getInstList().push_front(newPHI); - PN->removeIncomingValue(TL_ExitBlock); - PN->addIncoming(newPHI, TL_ExitBlock); + newPHI->addIncoming(V1, A_ExitingBlock); + A_ExitBlock->getInstList().push_front(newPHI); + PN->removeIncomingValue(A_ExitBlock); + PN->addIncoming(newPHI, A_ExitBlock); } else break; } + //[*] Eliminate split condition's inactive branch from ALoop. + BasicBlock *A_SplitCondBlock = SD.SplitCondition->getParent(); + BranchInst *A_BR = cast(A_SplitCondBlock->getTerminator()); + BasicBlock *A_InactiveBranch = A_BR->getSuccessor(1); + BasicBlock *A_ActiveBranch = A_BR->getSuccessor(1); + A_BR->setUnconditionalDest(A_BR->getSuccessor(0)); + removeBlocks(A_InactiveBranch, L, A_ActiveBranch); + + //[*] Eliminate split condition's inactive branch in from BLoop. + BasicBlock *B_SplitCondBlock = cast(ValueMap[A_SplitCondBlock]); + BranchInst *B_BR = cast(B_SplitCondBlock->getTerminator()); + BasicBlock *B_InactiveBranch = B_BR->getSuccessor(0); + BasicBlock *B_ActiveBranch = B_BR->getSuccessor(1); + B_BR->setUnconditionalDest(B_BR->getSuccessor(1)); + removeBlocks(B_InactiveBranch, BLoop, B_ActiveBranch); + return true; } From baldrick at free.fr Wed Aug 22 14:36:10 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 19:36:10 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41288 - /llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Message-ID: <200708221936.l7MJaAmV019394@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 14:36:09 2007 New Revision: 41288 URL: http://llvm.org/viewvc/llvm-project?rev=41288&view=rev Log: Change to LLVM local tag. Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.c?rev=41288&r1=41287&r2=41288&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/i386.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Wed Aug 22 14:36:09 2007 @@ -20455,7 +20455,7 @@ else if (IDENTIFIER_POINTER (arg)[1] == 'x') mode = SFmode; else if (IDENTIFIER_POINTER (arg)[1] == 'm') - /* APPLE LOCAL llvm - Force MMX to use a vector mode: PR1222. */ + /* LLVM LOCAL - Force MMX to use a vector mode: PR1222. */ mode = V2SImode; if (mode != VOIDmode) From alenhar2 at cs.uiuc.edu Wed Aug 22 14:36:32 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 22 Aug 2007 19:36:32 -0000 Subject: [llvm-commits] [llvm] r41289 - /llvm/trunk/test/CodeGen/PowerPC/no-dead-strip.ll Message-ID: <200708221936.l7MJaWxV019416@zion.cs.uiuc.edu> Author: alenhar2 Date: Wed Aug 22 14:36:31 2007 New Revision: 41289 URL: http://llvm.org/viewvc/llvm-project?rev=41289&view=rev Log: update test to check that codegen works with llvm.used in llvm.metadata section Modified: llvm/trunk/test/CodeGen/PowerPC/no-dead-strip.ll Modified: llvm/trunk/test/CodeGen/PowerPC/no-dead-strip.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/no-dead-strip.ll?rev=41289&r1=41288&r2=41289&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/no-dead-strip.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/no-dead-strip.ll Wed Aug 22 14:36:31 2007 @@ -4,5 +4,5 @@ target triple = "powerpc-apple-darwin8.8.0" @X = weak global i32 0 ; [#uses=1] @.str = internal constant [4 x i8] c"t.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] - at llvm.used = appending global [1 x i8*] [ i8* bitcast (i32* @X to i8*) ] ; <[1 x i8*]*> [#uses=0] + at llvm.used = appending global [1 x i8*] [ i8* bitcast (i32* @X to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] From baldrick at free.fr Wed Aug 22 14:38:04 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 21:38:04 +0200 Subject: [llvm-commits] [llvm-gcc-4.2] r41271 - /llvm-gcc-4.2/trunk/gcc/fold-const.c In-Reply-To: References: <200708221440.l7MEex1Y007217@zion.cs.uiuc.edu> Message-ID: <200708222138.05463.baldrick@free.fr> > > URL: http://llvm.org/viewvc/llvm-project?rev=41271&view=rev > > Log: > > Make sure that the overflow flag is not lost. > > Ick, is this hack to fold-const really appropriate? Yes, it is a backport from gcc mainline (commit 121252) and fixes a real problem with the Ada front-end. Ciao, Duncan. From baldrick at free.fr Wed Aug 22 14:53:19 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 19:53:19 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41290 - /llvm-gcc-4.2/trunk/gcc/fold-const.c Message-ID: <200708221953.l7MJrJKn020285@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 14:53:18 2007 New Revision: 41290 URL: http://llvm.org/viewvc/llvm-project?rev=41290&view=rev Log: Format as in mainline, and mention the corresponding gcc revision. Note that this is only the correctness part of Roger Sayle's patch 121251, not the efficiency improvement in round_up. Original changelog entry: 2007-01-27 Roger Sayle * fold-const.c (size_binop): In the fast-paths for X+0, 0+X, X-0 and 1*X check that the constant hasn't overflowed, to preserve the TREE_OVERFLOW bit. (round_up): Provide an efficient implementation when rouding-up an INTEGER_CST to a power-of-two. Modified: llvm-gcc-4.2/trunk/gcc/fold-const.c Modified: llvm-gcc-4.2/trunk/gcc/fold-const.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/fold-const.c?rev=41290&r1=41289&r2=41290&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/fold-const.c (original) +++ llvm-gcc-4.2/trunk/gcc/fold-const.c Wed Aug 22 14:53:18 2007 @@ -1890,22 +1890,25 @@ if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) { /* And some specific cases even faster than that. */ -/* LLVM local begin */ - if (code == PLUS_EXPR && integer_zerop (arg0) - && !TREE_OVERFLOW (arg0)) -/* LLVM local end */ - return arg1; - else if ((code == MINUS_EXPR || code == PLUS_EXPR) -/* LLVM local begin */ - && integer_zerop (arg1) - && !TREE_OVERFLOW (arg1)) -/* LLVM local end */ - return arg0; -/* LLVM local begin */ - else if (code == MULT_EXPR && integer_onep (arg0) - && !TREE_OVERFLOW (arg0)) -/* LLVM local end */ - return arg1; + /* LLVM local begin gcc 121252 */ + if (code == PLUS_EXPR) + { + if (integer_zerop (arg0) && !TREE_OVERFLOW (arg0)) + return arg1; + if (integer_zerop (arg1) && !TREE_OVERFLOW (arg1)) + return arg0; + } + else if (code == MINUS_EXPR) + { + if (integer_zerop (arg1) && !TREE_OVERFLOW (arg1)) + return arg0; + } + else if (code == MULT_EXPR) + { + if (integer_onep (arg0) && !TREE_OVERFLOW (arg0)) + return arg1; + } + /* LLVM local end gcc 121252 */ /* Handle general case of two integer constants. */ return int_const_binop (code, arg0, arg1, 0); From alenhar2 at cs.uiuc.edu Wed Aug 22 15:06:12 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 22 Aug 2007 20:06:12 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41291 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200708222006.l7MK6CvC020702@zion.cs.uiuc.edu> Author: alenhar2 Date: Wed Aug 22 15:06:12 2007 New Revision: 41291 URL: http://llvm.org/viewvc/llvm-project?rev=41291&view=rev Log: this tree too as per Duncan\'s request Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=41291&r1=41290&r2=41291&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Aug 22 15:06:12 2007 @@ -484,8 +484,10 @@ const Type *SBP = PointerType::get(Type::Int8Ty); ArrayType *AT = ArrayType::get(SBP, AttributeUsedGlobals.size()); Constant *Init = ConstantArray::get(AT, AttributeUsedGlobals); - new GlobalVariable(AT, false, GlobalValue::AppendingLinkage, Init, + GlobalValue *gv = new GlobalVariable(AT, false, + GlobalValue::AppendingLinkage, Init, "llvm.used", TheModule); + gv->setSection("llvm.metadata"); AttributeUsedGlobals.clear(); } From dpatel at apple.com Wed Aug 22 15:55:18 2007 From: dpatel at apple.com (Devang Patel) Date: Wed, 22 Aug 2007 20:55:18 -0000 Subject: [llvm-commits] [llvm] r41292 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708222055.l7MKtIfP022392@zion.cs.uiuc.edu> Author: dpatel Date: Wed Aug 22 15:55:18 2007 New Revision: 41292 URL: http://llvm.org/viewvc/llvm-project?rev=41292&view=rev Log: Fix typo. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41292&r1=41291&r2=41292&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Wed Aug 22 15:55:18 2007 @@ -898,7 +898,7 @@ BasicBlock *A_SplitCondBlock = SD.SplitCondition->getParent(); BranchInst *A_BR = cast(A_SplitCondBlock->getTerminator()); BasicBlock *A_InactiveBranch = A_BR->getSuccessor(1); - BasicBlock *A_ActiveBranch = A_BR->getSuccessor(1); + BasicBlock *A_ActiveBranch = A_BR->getSuccessor(0); A_BR->setUnconditionalDest(A_BR->getSuccessor(0)); removeBlocks(A_InactiveBranch, L, A_ActiveBranch); From clattner at apple.com Wed Aug 22 15:57:58 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 22 Aug 2007 13:57:58 -0700 Subject: [llvm-commits] [llvm] r41286 - /llvm/trunk/lib/CodeGen/AsmPrinter.cpp In-Reply-To: <200708221933.l7MJXBs6019270@zion.cs.uiuc.edu> References: <200708221933.l7MJXBs6019270@zion.cs.uiuc.edu> Message-ID: Thanks Andrew! -Chris On Aug 22, 2007, at 12:33 PM, Andrew Lenharth wrote: > Author: alenhar2 > Date: Wed Aug 22 14:33:11 2007 > New Revision: 41286 > > URL: http://llvm.org/viewvc/llvm-project?rev=41286&view=rev > Log: > move this check. ppc outputs .no_dead_strip properly > > Modified: > llvm/trunk/lib/CodeGen/AsmPrinter.cpp > > Modified: llvm/trunk/lib/CodeGen/AsmPrinter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ > AsmPrinter.cpp?rev=41286&r1=41285&r2=41286&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/CodeGen/AsmPrinter.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter.cpp Wed Aug 22 14:33:11 2007 > @@ -314,6 +314,12 @@ > /// special global used by LLVM. If so, emit it and return true, > otherwise > /// do nothing and return false. > bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { > + if (GV->getName() == "llvm.used") { > + if (TAI->getUsedDirective() != 0) // No need to emit this > at all. > + EmitLLVMUsedList(GV->getInitializer()); > + return true; > + } > + > // Ignore debug and non-emitted data. > if (GV->getSection() == "llvm.metadata") return true; > > @@ -321,12 +327,6 @@ > > assert(GV->hasInitializer() && "Not a special LLVM global!"); > > - if (GV->getName() == "llvm.used") { > - if (TAI->getUsedDirective() != 0) // No need to emit this > at all. > - EmitLLVMUsedList(GV->getInitializer()); > - return true; > - } > - > const TargetData *TD = TM.getTargetData(); > unsigned Align = Log2_32(TD->getPointerPrefAlignment()); > if (GV->getName() == "llvm.global_ctors" && GV->use_empty()) { > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Wed Aug 22 15:59:21 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 22 Aug 2007 13:59:21 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r41290 - /llvm-gcc-4.2/trunk/gcc/fold-const.c In-Reply-To: <200708221953.l7MJrJKn020285@zion.cs.uiuc.edu> References: <200708221953.l7MJrJKn020285@zion.cs.uiuc.edu> Message-ID: On Aug 22, 2007, at 12:53 PM, Duncan Sands wrote: > Author: baldrick > Date: Wed Aug 22 14:53:18 2007 > New Revision: 41290 > > URL: http://llvm.org/viewvc/llvm-project?rev=41290&view=rev > Log: > Format as in mainline, and mention the corresponding > gcc revision. Note that this is only the correctness > part of Roger Sayle's patch 121251, not the efficiency > improvement in round_up. Original changelog entry: Ah, very nice ok, I get it :) > 2007-01-27 Roger Sayle Yay, this was before GPLv3 :) -Chris From dpatel at apple.com Wed Aug 22 16:07:41 2007 From: dpatel at apple.com (Devang Patel) Date: Wed, 22 Aug 2007 21:07:41 -0000 Subject: [llvm-commits] [llvm] r41295 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708222107.l7ML7fmD022737@zion.cs.uiuc.edu> Author: dpatel Date: Wed Aug 22 16:07:41 2007 New Revision: 41295 URL: http://llvm.org/viewvc/llvm-project?rev=41295&view=rev Log: Remove dead code. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41295&r1=41294&r2=41295&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Wed Aug 22 16:07:41 2007 @@ -641,7 +641,6 @@ PredBlocks.push_back(P); } - BasicBlock *NewDominator = NULL; for(BasicBlock::iterator FBI = FrontierBB->begin(), FBE = FrontierBB->end(); FBI != FBE; ++FBI) { if (PHINode *PN = dyn_cast(FBI)) { @@ -650,10 +649,6 @@ BasicBlock *P = *PI; PN->removeIncomingValue(P); } - // If we have not identified new dominator then see if we can identify - // one based on remaining incoming PHINode values. - if (NewDominator == NULL && PN->getNumIncomingValues() == 1) - NewDominator = PN->getIncomingBlock(0); } else break; From tonic at nondot.org Wed Aug 22 16:18:40 2007 From: tonic at nondot.org (Tanya Lattner) Date: Wed, 22 Aug 2007 21:18:40 -0000 Subject: [llvm-commits] [test-suite] r41296 - /test-suite/trunk/SingleSource/UnitTests/Vector/sumarray.c Message-ID: <200708222118.l7MLIewU023091@zion.cs.uiuc.edu> Author: tbrethou Date: Wed Aug 22 16:18:40 2007 New Revision: 41296 URL: http://llvm.org/viewvc/llvm-project?rev=41296&view=rev Log: void main() return value is undefined. Change to return 0. Modified: test-suite/trunk/SingleSource/UnitTests/Vector/sumarray.c Modified: test-suite/trunk/SingleSource/UnitTests/Vector/sumarray.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Vector/sumarray.c?rev=41296&r1=41295&r2=41296&view=diff ============================================================================== --- test-suite/trunk/SingleSource/UnitTests/Vector/sumarray.c (original) +++ test-suite/trunk/SingleSource/UnitTests/Vector/sumarray.c Wed Aug 22 16:18:40 2007 @@ -7,7 +7,7 @@ union Array TheArray; -void main() { +int main() { int i; v4sf sum = { 0, 0, 0, 0}; FV sumFV; @@ -19,4 +19,5 @@ sumFV.V = sum; printFV(&sumFV); + return 0; } From tonic at nondot.org Wed Aug 22 16:24:52 2007 From: tonic at nondot.org (Tanya Lattner) Date: Wed, 22 Aug 2007 21:24:52 -0000 Subject: [llvm-commits] [test-suite] r41297 - /test-suite/trunk/SingleSource/Regression/C/DuffsDevice.c Message-ID: <200708222124.l7MLOqhM023402@zion.cs.uiuc.edu> Author: tbrethou Date: Wed Aug 22 16:24:52 2007 New Revision: 41297 URL: http://llvm.org/viewvc/llvm-project?rev=41297&view=rev Log: main should return 0. Modified: test-suite/trunk/SingleSource/Regression/C/DuffsDevice.c Modified: test-suite/trunk/SingleSource/Regression/C/DuffsDevice.c URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Regression/C/DuffsDevice.c?rev=41297&r1=41296&r2=41297&view=diff ============================================================================== --- test-suite/trunk/SingleSource/Regression/C/DuffsDevice.c (original) +++ test-suite/trunk/SingleSource/Regression/C/DuffsDevice.c Wed Aug 22 16:24:52 2007 @@ -24,7 +24,7 @@ } } -void main() { +int main() { short Array[100]; short Sum = 0; int i; @@ -35,4 +35,5 @@ sum(&Sum, Array, 100); printf("Sum is %d\n", Sum); + return 0; } From baldrick at free.fr Wed Aug 22 18:39:55 2007 From: baldrick at free.fr (Duncan Sands) Date: Wed, 22 Aug 2007 23:39:55 -0000 Subject: [llvm-commits] [llvm] r41304 - /llvm/trunk/docs/LangRef.html Message-ID: <200708222339.l7MNdtAI027580@zion.cs.uiuc.edu> Author: baldrick Date: Wed Aug 22 18:39:54 2007 New Revision: 41304 URL: http://llvm.org/viewvc/llvm-project?rev=41304&view=rev Log: Implement review feedback on trampoline documentation. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=41304&r1=41303&r2=41304&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Wed Aug 22 18:39:54 2007 @@ -5171,9 +5171,6 @@ The call %val = call i32 %fp( i32 %x, i32 %y ) is then equivalent to %val = call i32 %f( i8* %nval, i32 %x, i32 %y ).

-

- Trampolines are currently only supported on the X86 architecture. -

@@ -5194,9 +5191,10 @@ The llvm.init.trampoline intrinsic takes three arguments, all pointers. The tramp argument must point to a sufficiently large and sufficiently aligned block of memory; this memory is written to by the - intrinsic. Currently LLVM provides no help in determining just how big and - aligned the memory needs to be. The func argument must hold a - function bitcast to an i8*. + intrinsic. Note that the size and the alignment are target-specific - LLVM + currently provides no portable way of determining them, so a front-end that + generates this intrinsic needs to have some target-specific knowledge. + The func argument must hold a function bitcast to an i8*.

Semantics:

From baldrick at free.fr Wed Aug 22 18:57:00 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 23 Aug 2007 01:57:00 +0200 Subject: [llvm-commits] [llvm] r40549 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ include/llvm/Target/ lib/AsmParser/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/VMCore/ In-Reply-To: References: <200707271258.l6RCwus3032767@zion.cs.uiuc.edu> Message-ID: <200708230157.04393.baldrick@free.fr> Hi Chris, > Nice summary. Dummy question: it isn't possible to merge the init > and adjust intrinsics, is it? If the result of init can only be used > by adjust, it seems reasonable to merge them. yes they can be merged, but that would require some gcc hacking (not trivial, but not hard either). The reason is that gcc currently stores the memory for the trampoline in the frame object that gets passed around to nested functions. When a nested functions wants to call the trampoline, it takes the address of this memory from the object it was passed and calls adjust_trampoline on it - this can happen far away from the trampoline initialization. What would need to be done is to move the memory out of the frame object and into an alloca, and store a function pointer inside the frame object instead. init_trampoline would then initialize the trampoline memory and generate the function pointer, which would then be stored in the frame object. Shall I do it? > LangRef.html should not describe implementation state, please remove > this comment. Done. > I would suggest changing this last sentence to: > > "Note that this size is target-specific - LLVM currently provides no > portable way to determine the size or alignment to use for the > memory, so a front-end that generates this intrinsic must have some > target-specific knowledge." Done. > > +SDOperand ARMTargetLowering::LowerADJUST_TRAMP(SDOperand Op, > > + SelectionDAG > > &DAG) { > > + // Thumb trampolines should be entered in thumb mode, so set the > > bottom bit > > + // of the address. > > + return DAG.getNode(ISD::OR, MVT::i32, Op.getOperand(0), > > + DAG.getConstant(1, MVT::i32)); > > This may or may not be right in the future. For now, both GCC and > LLVM compile an entire file in thumb or in arm mode. In the future, > we may mix and match functions as appropriate. Can you please add a > fixme to this saying that we should reevaluate it if the caller and > callee can ever be different ISAs. I don't know anything about ARM or thumb, but I think the reason is that the trampoline itself (i.e. the code on the stack) is written in thumb mode (remember that this is a canned sequence of instructions that are not generated by LLVM itself), and thus should be called via a pointer with the bottom bit set. The nested function itself, the code for which is generated by LLVM, can presumably be in thumb mode or not, and will have the mode encoded in the lower bit of its address in the usual way; when the trampoline jumps to it, the correct new mode should be set appropriately. So I don't see any problem here, assuming we copy the trampoline initializer from gcc (where it is a bunch of thumb mode opcodes). Ciao, Duncan. From isanbard at gmail.com Wed Aug 22 19:17:54 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Aug 2007 00:17:54 -0000 Subject: [llvm-commits] [test-suite] r41305 - /test-suite/trunk/SingleSource/Benchmarks/Misc-C++/sphereflake.cpp Message-ID: <200708230017.l7N0Hspa028707@zion.cs.uiuc.edu> Author: void Date: Wed Aug 22 19:17:54 2007 New Revision: 41305 URL: http://llvm.org/viewvc/llvm-project?rev=41305&view=rev Log: New testcase from http://ompf.org/ray/sphereflake/ Added: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/sphereflake.cpp Added: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/sphereflake.cpp URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc-C%2B%2B/sphereflake.cpp?rev=41305&view=auto ============================================================================== --- test-suite/trunk/SingleSource/Benchmarks/Misc-C++/sphereflake.cpp (added) +++ test-suite/trunk/SingleSource/Benchmarks/Misc-C++/sphereflake.cpp Wed Aug 22 19:17:54 2007 @@ -0,0 +1,178 @@ +// sphere flake bvh raytracer (c) 2005, thierry berger-perrin +// this code is released under the GNU Public License. +#include // see http://ompf.org/ray/sphereflake/ +#include // compile with ie g++ -O2 -ffast-math sphereflake.cc +#define GIMME_SHADOWS // usage: ./sphereflake [lvl=6] >pix.ppm + +enum { childs = 9, ss= 2, ss_sqr = ss*ss }; /* not really tweakable anymore */ +static const double infinity = 1./0, epsilon = 1e-12; + +struct v_t{ double x,y,z;v_t(){} + v_t(const double a,const double b,const double c):x(a),y(b),z(c){} + v_t operator+(const v_t&v)const{return v_t(x+v.x,y+v.y,z+v.z);} + v_t operator-(const v_t&v)const{return v_t(x-v.x,y-v.y,z-v.z);} + v_t operator-()const{return v_t(-x,-y,-z);} + v_t operator*(const double d)const{return v_t(x*d,y*d,z*d);} + v_t cross(const v_t&v)const{return v_t(y*v.z-z*v.y,z*v.x-x*v.z,x*v.y-y*v.x);} + v_t norm()const{return*this*(1./sqrt(magsqr()));} + double dot(const v_t&v)const{return x*v.x+y*v.y+z*v.z;} + double magsqr()const{return dot(*this);} +}; + +//static const v_t light(v_t(0.5,-.95,1.775).norm()); /*pick one*/ +static const v_t light(v_t(-0.5,-.65,.9).norm()); /*fiat lux*/ + +struct ray_t{ + v_t o,d; + ray_t(const v_t&v):o(v){} + ray_t(const v_t&v,const v_t&w):o(v),d(w){} +}; +struct hit_t { + v_t n; + double t; + hit_t():n(v_t(0,0,0)),t(infinity){} +}; + +struct sphere_t{ + v_t o; + double r; + sphere_t(){} + sphere_t(const v_t&v,double d):o(v),r(d){} + v_t get_normal(const v_t&v)const{return(v-o)*(1./r);} + double intersect(const ray_t&ray)const{ + const v_t v(o-ray.o); const double b=ray.d.dot(v),disc=b*b-v.magsqr()+r*r; + if(disc < 0.) + return infinity; /*branch away from the square root*/ + const double d=sqrt(disc), t2=b+d, t1=b-d; /*cond. move*/ + if(t2 < 0.) + return infinity; + else + return(t1 > 0.? t1 : t2); + } +}; + +struct node_t; +static node_t *pool=0, *end=0; + +struct node_t { /*a bvh in array form+skip for navigation.*/ + sphere_t bound,leaf; + long diff;/*far from optimal*/ + node_t(){} node_t(const sphere_t&b,const sphere_t&l,const long jump) :bound(b),leaf(l),diff(jump){} + template static void intersect(const ray_t &ray,hit_t &hit){ + const node_t*p=pool; + while(p < end) { + if(p->bound.intersect(ray)>=hit.t) /*missed bound*/ + p+=p->diff; /*skip subtree*/ + else{ + const double t=p->leaf.intersect(ray); + if(t < hit.t) { /*if hit, update, then break for shadows*/ + hit.t=t; + if(shadow) break; + hit.n=p->leaf.get_normal(ray.o+ray.d*t); + } + ++p; /*next!*/ + } + } + } +}; + +static double ray_trace(const node_t*const scene,const ray_t&ray) { + hit_t hit; + scene->intersect(ray,hit);// trace primary + const double diffuse = hit.t==infinity ? 0. : -hit.n.dot(light); + #ifdef GIMME_SHADOWS + if (diffuse <= 0.) + return 0.; + const ray_t sray(ray.o+(ray.d*hit.t)+(hit.n*epsilon),-light); + hit_t shit; + scene->intersect(sray,shit);// trace shadow + return shit.t==infinity ? diffuse : 0.; + #else + return diffuse > 0. ? diffuse : 0.; + #endif +} + +static const double grid[ss_sqr][2]={ /*our rotated grid*/ + {-3/3.,-1/3.},{+1/3.,-3/3.}, + {-1/3.,+3/3.},{+3/3.,+1/3.} +}; +static void trace_rgss(const int width,const int height) { + const double w=width,h=height,rcp=1/double(ss),scale=256./double(ss_sqr); + ray_t ray(v_t(0,0,-4.5)); /* eye, looking into Z */ + v_t rgss[ss_sqr]; + for(int i=0;in.x*n.x) { + if(n.y*n.y>n.z*n.z) + b1.y=-b1.y; + else b1.z=-b1.z; + } + else if(n.z*n.z > n.x*n.x) + b1.z=-b1.z; + else b1.x=-b1.x; + } + else + b1=v_t(n.z,n.x,n.y);/*leaves some cases out,dodge them*/ + + up=n; + b2=up.cross(b1); + b1=up.cross(b2); + } +}; + +static node_t *create(node_t*n,const int lvl,int dist,v_t c,v_t d,double r) { + n = 1 + new (n) node_t(sphere_t(c,2.*r),sphere_t(c,r), lvl > 1 ? dist : 1); + if (lvl <= 1) + return n; /*if not at the bottom, recurse a bit more*/ + + dist=std::max((dist-childs)/childs,1); const basis_t b(d); + const double nr=r*1/3.,daL=2.*M_PI/6.,daU=2.*M_PI/3.; double a=0; + for(int i=0;i<6;++i){ /*lower ring*/ + const v_t ndir((d*-.2+b.b1*sin(a)+b.b2*cos(a)).norm()); /*transcendentals?!*/ + n=create(n,lvl-1,dist,c+ndir*(r+nr),ndir,nr); + a+=daL; + } + a-=daL/3.;/*tweak*/ + for(int i=0;i<3;++i){ /*upper ring*/ + const v_t ndir((d*+.6+b.b1*sin(a)+b.b2*cos(a)).norm()); + n=create(n,lvl-1,dist,c+ndir*(r+nr),ndir,nr); a+=daU; + } + return n; +} + +int main(int argc,char*argv[]){ + enum{ w = 1024, h = w }; /* resolution */ + const int lvl=(argc==2?std::max(atoi(argv[1]),2):6); + int count=childs, dec=lvl; + while(--dec > 1) count=(count*childs)+childs; + ++count; + std::cerr << count << " spheres,claiming " << (count*sizeof(node_t))/(1024.*1024) << " MB." << std::endl; + pool=new node_t[count]; /* raw */ + end=pool+count; + create(pool,lvl,count,v_t(0,0,0),v_t(+.25,+1,-.5).norm(),1.); /* cooked */ + std::cout << "P2\n" << w << " " << h << "\n256\n"; + trace_rgss(w,h); /* served */ + return 0; +} From isanbard at gmail.com Wed Aug 22 19:18:15 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Aug 2007 00:18:15 -0000 Subject: [llvm-commits] [test-suite] r41306 - /test-suite/trunk/SingleSource/Benchmarks/Misc-C++/ray.cpp Message-ID: <200708230018.l7N0IFB4028733@zion.cs.uiuc.edu> Author: void Date: Wed Aug 22 19:18:15 2007 New Revision: 41306 URL: http://llvm.org/viewvc/llvm-project?rev=41306&view=rev Log: New testcase from http://www.ffconsultancy.com/languages/ray_tracer/comparison.html Added: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/ray.cpp Added: test-suite/trunk/SingleSource/Benchmarks/Misc-C++/ray.cpp URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc-C%2B%2B/ray.cpp?rev=41306&view=auto ============================================================================== --- test-suite/trunk/SingleSource/Benchmarks/Misc-C++/ray.cpp (added) +++ test-suite/trunk/SingleSource/Benchmarks/Misc-C++/ray.cpp Wed Aug 22 19:18:15 2007 @@ -0,0 +1,122 @@ +#include +#include +#include +#include + +using namespace std; + +numeric_limits real; +double delta = sqrt(real.epsilon()), infinity = real.infinity(); + +struct Vec { + double x, y, z; + Vec(double x2, double y2, double z2) : x(x2), y(y2), z(z2) {} +}; +Vec operator+(const Vec &a, const Vec &b) +{ return Vec(a.x+b.x, a.y+b.y, a.z+b.z); } +Vec operator-(const Vec &a, const Vec &b) +{ return Vec(a.x-b.x, a.y-b.y, a.z-b.z); } +Vec operator*(double a, const Vec &b) { return Vec(a*b.x, a*b.y, a*b.z); } +double dot(const Vec &a, const Vec &b) { return a.x*b.x + a.y*b.y + a.z*b.z; } +Vec unitise(const Vec &a) { return (1 / sqrt(dot(a, a))) * a; } + +typedef pair Hit; + +struct Ray { + Vec orig, dir; + Ray(const Vec &o, const Vec &d) : orig(o), dir(d) {} +}; + +struct Scene { + virtual ~Scene() {}; + virtual Hit intersect(const Hit &, const Ray &) const = 0; +}; + +struct Sphere : public Scene { + Vec center; + double radius; + + Sphere(Vec c, double r) : center(c), radius(r) {} + ~Sphere() {} + + double ray_sphere(const Ray &ray) const { + Vec v = center - ray.orig; + double b = dot(v, ray.dir), disc = b*b - dot(v, v) + radius * radius; + if (disc < 0) return infinity; + double d = sqrt(disc), t2 = b + d; + if (t2 < 0) return infinity; + double t1 = b - d; + return (t1 > 0 ? t1 : t2); + } + + Hit intersect(const Hit &hit, const Ray &ray) const { + double lambda = ray_sphere(ray); + if (lambda >= hit.first) return hit; + return Hit(lambda, unitise(ray.orig + lambda*ray.dir - center)); + } +}; + +typedef list Scenes; +struct Group : public Scene { + Sphere bound; + Scenes child; + + Group(Sphere b, Scenes c) : bound(b), child(c) {} + ~Group() { + for (Scenes::const_iterator it=child.begin(); it!=child.end(); ++it) + delete *it; + } + + Hit intersect(const Hit &hit, const Ray &ray) const { + Hit hit2=hit; + double l = bound.ray_sphere(ray); + if (l >= hit.first) return hit; + for (Scenes::const_iterator it=child.begin(); it!=child.end(); ++it) + hit2 = (*it)->intersect(hit2, ray); + return hit2; + } +}; + +Hit intersect(const Ray &ray, const Scene &s) +{ return s.intersect(Hit(infinity, Vec(0, 0, 0)), ray); } + +double ray_trace(const Vec &light, const Ray &ray, const Scene &s) { + Hit hit = intersect(ray, s); + if (hit.first == infinity) return 0; + double g = dot(hit.second, light); + if (g >= 0) return 0.; + Vec p = ray.orig + hit.first*ray.dir + delta*hit.second; + return (intersect(Ray(p, -1. * light), s).first < infinity ? 0 : -g); +} + +Scene *create(int level, const Vec &c, double r) { + Scene *s = new Sphere(c, r); + if (level == 1) return s; + Scenes child; + child.push_back(s); + double rn = 3*r/sqrt(12.); + for (int dz=-1; dz<=1; dz+=2) + for (int dx=-1; dx<=1; dx+=2) + child.push_back(create(level-1, c + rn*Vec(dx, 1, dz), r/2)); + return new Group(Sphere(c, 3*r), child); +} + +int main(int argc, char *argv[]) { + int level = 6, n = 512, ss = 4; + if (argc == 2) level = atoi(argv[1]); + Vec light = unitise(Vec(-1, -3, 2)); + Scene *s(create(level, Vec(0, -1, 0), 1)); + cout << "P5\n" << n << " " << n << "\n255\n"; + for (int y=n-1; y>=0; --y) + for (int x=0; x Author: lattner Date: Thu Aug 23 00:15:32 2007 New Revision: 41309 URL: http://llvm.org/viewvc/llvm-project?rev=41309&view=rev Log: rename APInt::toString -> toStringUnsigned for symmetry with toStringSigned() Add an APSInt::toString() method. Modified: llvm/trunk/examples/Fibonacci/fibonacci.cpp llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp llvm/trunk/include/llvm/ADT/APInt.h llvm/trunk/include/llvm/ADT/APSInt.h llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp llvm/trunk/lib/Support/APInt.cpp llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Modified: llvm/trunk/examples/Fibonacci/fibonacci.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Fibonacci/fibonacci.cpp?rev=41309&r1=41308&r2=41309&view=diff ============================================================================== --- llvm/trunk/examples/Fibonacci/fibonacci.cpp (original) +++ llvm/trunk/examples/Fibonacci/fibonacci.cpp Thu Aug 23 00:15:32 2007 @@ -116,6 +116,6 @@ GenericValue GV = EE->runFunction(FibF, Args); // import result of execution - std::cout << "Result: " << GV.IntVal.toString(10) << "\n"; + std::cout << "Result: " << GV.IntVal.toStringUnsigned(10) << "\n"; return 0; } Modified: llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp?rev=41309&r1=41308&r2=41309&view=diff ============================================================================== --- llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp (original) +++ llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp Thu Aug 23 00:15:32 2007 @@ -107,6 +107,6 @@ GenericValue gv = EE->runFunction(FooF, noargs); // Import result of execution: - std::cout << "Result: " << gv.IntVal.toString(10) << "\n"; + std::cout << "Result: " << gv.IntVal.toStringUnsigned(10) << "\n"; return 0; } Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=41309&r1=41308&r2=41309&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Thu Aug 23 00:15:32 2007 @@ -932,7 +932,7 @@ /// radix given. The radix can be 2, 8, 10 or 16. /// @returns a character interpretation of the APInt /// @brief Convert unsigned APInt to string representation. - inline std::string toString(uint8_t radix = 10) const { + inline std::string toStringUnsigned(uint8_t radix = 10) const { return toString(radix, false); } Modified: llvm/trunk/include/llvm/ADT/APSInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APSInt.h?rev=41309&r1=41308&r2=41309&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APSInt.h (original) +++ llvm/trunk/include/llvm/ADT/APSInt.h Thu Aug 23 00:15:32 2007 @@ -52,6 +52,12 @@ void setIsUnsigned(bool Val) { IsUnsigned = Val; } void setIsSigned(bool Val) { IsUnsigned = !Val; } + /// This is used internally to convert an APInt to a string. + /// @brief Converts an APInt to a std::string + std::string toString(uint8_t Radix) const { + return toString(Radix, isSigned()); + } + const APSInt &operator%=(const APSInt &RHS) { assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp?rev=41309&r1=41308&r2=41309&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Thu Aug 23 00:15:32 2007 @@ -1346,8 +1346,9 @@ case Type::DoubleTyID: DOUT << "double " << Val.DoubleVal; break; case Type::PointerTyID: DOUT << "void* " << intptr_t(Val.PointerVal); break; case Type::IntegerTyID: - DOUT << "i" << Val.IntVal.getBitWidth() << " " << Val.IntVal.toString(10) - << " (0x" << Val.IntVal.toString(16) << ")\n"; + DOUT << "i" << Val.IntVal.getBitWidth() << " " + << Val.IntVal.toStringUnsigned(10) + << " (0x" << Val.IntVal.toStringUnsigned(16) << ")\n"; break; } } Modified: llvm/trunk/lib/Support/APInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=41309&r1=41308&r2=41309&view=diff ============================================================================== --- llvm/trunk/lib/Support/APInt.cpp (original) +++ llvm/trunk/lib/Support/APInt.cpp Thu Aug 23 00:15:32 2007 @@ -2008,8 +2008,8 @@ else for (unsigned i = getNumWords(); i > 0; i--) { cerr << pVal[i-1] << " "; } - cerr << " U(" << this->toString(10) << ") S(" << this->toStringSigned(10) - << ")\n" << std::setbase(10); + cerr << " U(" << this->toStringUnsigned(10) << ") S(" + << this->toStringSigned(10) << ")\n" << std::setbase(10); } #endif Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=41309&r1=41308&r2=41309&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Thu Aug 23 00:15:32 2007 @@ -519,7 +519,7 @@ std::string NewName = I->getName(); for (unsigned i = 0, e = Operands.size(); i != e; ++i) if (ConstantInt *CI = dyn_cast(Operands[i])) - NewName += "." + CI->getValue().toString(10); + NewName += "." + CI->getValue().toStringUnsigned(10); else NewName += ".x"; TheArg->setName(NewName+".val"); From sabre at nondot.org Thu Aug 23 00:20:48 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 23 Aug 2007 05:20:48 -0000 Subject: [llvm-commits] [llvm] r41310 - /llvm/trunk/include/llvm/ADT/APSInt.h Message-ID: <200708230520.l7N5Kmrs003550@zion.cs.uiuc.edu> Author: lattner Date: Thu Aug 23 00:20:48 2007 New Revision: 41310 URL: http://llvm.org/viewvc/llvm-project?rev=41310&view=rev Log: Avoid hiding issues. Modified: llvm/trunk/include/llvm/ADT/APSInt.h Modified: llvm/trunk/include/llvm/ADT/APSInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APSInt.h?rev=41310&r1=41309&r2=41310&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APSInt.h (original) +++ llvm/trunk/include/llvm/ADT/APSInt.h Thu Aug 23 00:20:48 2007 @@ -55,7 +55,7 @@ /// This is used internally to convert an APInt to a string. /// @brief Converts an APInt to a std::string std::string toString(uint8_t Radix) const { - return toString(Radix, isSigned()); + return APInt::toString(Radix, isSigned()); } From sabre at nondot.org Thu Aug 23 00:21:48 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 23 Aug 2007 05:21:48 -0000 Subject: [llvm-commits] [llvm] r41311 - /llvm/trunk/include/llvm/ADT/APSInt.h Message-ID: <200708230521.l7N5LmSv003592@zion.cs.uiuc.edu> Author: lattner Date: Thu Aug 23 00:21:48 2007 New Revision: 41311 URL: http://llvm.org/viewvc/llvm-project?rev=41311&view=rev Log: default this to radix 10 like the toString(Un)Signed methods. Modified: llvm/trunk/include/llvm/ADT/APSInt.h Modified: llvm/trunk/include/llvm/ADT/APSInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APSInt.h?rev=41311&r1=41310&r2=41311&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APSInt.h (original) +++ llvm/trunk/include/llvm/ADT/APSInt.h Thu Aug 23 00:21:48 2007 @@ -54,7 +54,7 @@ /// This is used internally to convert an APInt to a string. /// @brief Converts an APInt to a std::string - std::string toString(uint8_t Radix) const { + std::string toString(uint8_t Radix = 10) const { return APInt::toString(Radix, isSigned()); } From asl at math.spbu.ru Thu Aug 23 02:21:07 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Thu, 23 Aug 2007 07:21:07 -0000 Subject: [llvm-commits] [llvm] r41316 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200708230721.l7N7L8FH007037@zion.cs.uiuc.edu> Author: asl Date: Thu Aug 23 02:21:06 2007 New Revision: 41316 URL: http://llvm.org/viewvc/llvm-project?rev=41316&view=rev Log: Perform correct codegen for eh_dwarf_cfa intrinsic. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=41316&r1=41315&r2=41316&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Aug 23 02:21:06 2007 @@ -2751,11 +2751,19 @@ case Intrinsic::eh_dwarf_cfa: { if (ExceptionHandling) { MVT::ValueType VT = getValue(I.getOperand(1)).getValueType(); + SDOperand CfaArg; + if (MVT::getSizeInBits(VT) > MVT::getSizeInBits(TLI.getPointerTy())) + CfaArg = DAG.getNode(ISD::TRUNCATE, + TLI.getPointerTy(), getValue(I.getOperand(1))); + else + CfaArg = DAG.getNode(ISD::SIGN_EXTEND, + TLI.getPointerTy(), getValue(I.getOperand(1))); + SDOperand Offset = DAG.getNode(ISD::ADD, TLI.getPointerTy(), DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET, - VT), - getValue(I.getOperand(1))); + TLI.getPointerTy()), + CfaArg); setValue(&I, DAG.getNode(ISD::ADD, TLI.getPointerTy(), DAG.getNode(ISD::FRAMEADDR, From sabre at nondot.org Thu Aug 23 10:16:04 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 23 Aug 2007 15:16:04 -0000 Subject: [llvm-commits] [llvm] r41318 - /llvm/trunk/lib/Target/PowerPC/README.txt Message-ID: <200708231516.l7NFG4Sc003844@zion.cs.uiuc.edu> Author: lattner Date: Thu Aug 23 10:16:03 2007 New Revision: 41318 URL: http://llvm.org/viewvc/llvm-project?rev=41318&view=rev Log: new example Modified: llvm/trunk/lib/Target/PowerPC/README.txt Modified: llvm/trunk/lib/Target/PowerPC/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/README.txt?rev=41318&r1=41317&r2=41318&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/README.txt (original) +++ llvm/trunk/lib/Target/PowerPC/README.txt Thu Aug 23 10:16:03 2007 @@ -117,6 +117,23 @@ Note that this (and the static variable version) is discussed here for GCC: http://gcc.gnu.org/ml/gcc-patches/2006-02/msg00133.html +Here's another example (the sgn function): +double testf(double a) { + return a == 0.0 ? 0.0 : (a > 0.0 ? 1.0 : -1.0); +} + +it produces a BB like this: +LBB1_1: ; cond_true + lis r2, ha16(LCPI1_0) + lfs f0, lo16(LCPI1_0)(r2) + lis r2, ha16(LCPI1_1) + lis r3, ha16(LCPI1_2) + lfs f2, lo16(LCPI1_2)(r3) + lfs f3, lo16(LCPI1_1)(r2) + fsub f0, f0, f1 + fsel f1, f0, f2, f3 + blr + ===-------------------------------------------------------------------------=== PIC Code Gen IPO optimization: From sabre at nondot.org Thu Aug 23 10:22:08 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 23 Aug 2007 15:22:08 -0000 Subject: [llvm-commits] [llvm] r41319 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200708231522.l7NFM8Pq004241@zion.cs.uiuc.edu> Author: lattner Date: Thu Aug 23 10:22:07 2007 New Revision: 41319 URL: http://llvm.org/viewvc/llvm-project?rev=41319&view=rev Log: add some notes on really poor codegen. Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=41319&r1=41318&r2=41319&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Thu Aug 23 10:22:07 2007 @@ -1134,3 +1134,47 @@ into any return registers :) //===---------------------------------------------------------------------===// + +The X86 backend should fold (branch (or (setcc, setcc))) into multiple +branches. We generate really poor code for: + +double testf(double a) { + return a == 0.0 ? 0.0 : (a > 0.0 ? 1.0 : -1.0); +} + +For example, the entry BB is: + +_testf: + subl $20, %esp + pxor %xmm0, %xmm0 + movsd 24(%esp), %xmm1 + ucomisd %xmm0, %xmm1 + setnp %al + sete %cl + testb %cl, %al + jne LBB1_5 # UnifiedReturnBlock +LBB1_1: # cond_true + + +it would be better to replace the last four instructions with: + + jp LBB1_1 + je LBB1_5 +LBB1_1: + +We also codegen the inner ?: into a diamond: + + cvtss2sd LCPI1_0(%rip), %xmm2 + cvtss2sd LCPI1_1(%rip), %xmm3 + ucomisd %xmm1, %xmm0 + ja LBB1_3 # cond_true +LBB1_2: # cond_true + movapd %xmm3, %xmm2 +LBB1_3: # cond_true + movapd %xmm2, %xmm0 + ret + +We should sink the load into xmm3 into the LBB1_2 block. This should +be pretty easy, and will nuke all the copies. + +//===---------------------------------------------------------------------===// From baldrick at free.fr Thu Aug 23 11:04:49 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 23 Aug 2007 16:04:49 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41322 - in /llvm-gcc-4.2/trunk/gcc/ada: a-numaux-x86.adb a-numaux-x86.ads Message-ID: <200708231604.l7NG4nAS006854@zion.cs.uiuc.edu> Author: baldrick Date: Thu Aug 23 11:04:48 2007 New Revision: 41322 URL: http://llvm.org/viewvc/llvm-project?rev=41322&view=rev Log: Work around the current lack of support for inline asm that uses the x86 floating point stack. Modified: llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads Modified: llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb?rev=41322&r1=41321&r2=41322&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb (original) +++ llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.adb Thu Aug 23 11:04:48 2007 @@ -37,11 +37,13 @@ -- This version of Numerics.Aux is for the IEEE Double Extended floating -- point format on x86. -with System.Machine_Code; use System.Machine_Code; +-- LLVM local +-- with System.Machine_Code; use System.Machine_Code; package body Ada.Numerics.Aux is - NL : constant String := ASCII.LF & ASCII.HT; +-- LLVM local +-- NL : constant String := ASCII.LF & ASCII.HT; ----------------------- -- Local subprograms -- @@ -55,6 +57,11 @@ -- to calculate the exponentiation. This is used by Pow for values -- for values of Y in the open interval (-0.25, 0.25) + -- LLVM local begin + pragma Import (C, Logarithmic_Pow, "pow"); + pragma Pure_Function (Logarithmic_Pow); + -- LLVM local end + procedure Reduce (X : in out Double; Q : out Natural); -- Implements reduction of X by Pi/2. Q is the quadrant of the final -- result in the range 0 .. 3. The absolute value of X is at most Pi. @@ -73,15 +80,18 @@ -- Atan -- ---------- + -- LLVM local begin + function C_Atan (X : Double) return Double; + pragma Import (C, C_Atan, "atan"); + pragma Pure_Function (C_Atan); + -- LLVM local end + function Atan (X : Double) return Double is Result : Double; begin - Asm (Template => - "fld1" & NL - & "fpatan", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", X)); + -- LLVM local + Result := C_Atan (X); -- The result value is NaN iff input was invalid @@ -96,25 +106,27 @@ -- Exp -- --------- - function Exp (X : Double) return Double is - Result : Double; - begin - Asm (Template => - "fldl2e " & NL - & "fmulp %%st, %%st(1)" & NL -- X * log2 (E) - & "fld %%st(0) " & NL - & "frndint " & NL -- Integer (X * Log2 (E)) - & "fsubr %%st, %%st(1)" & NL -- Fraction (X * Log2 (E)) - & "fxch " & NL - & "f2xm1 " & NL -- 2**(...) - 1 - & "fld1 " & NL - & "faddp %%st, %%st(1)" & NL -- 2**(Fraction (X * Log2 (E))) - & "fscale " & NL -- E ** X - & "fstp %%st(1) ", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", X)); - return Result; - end Exp; +-- LLVM local begin +-- function Exp (X : Double) return Double is +-- Result : Double; +-- begin +-- Asm (Template => +-- "fldl2e " & NL +-- & "fmulp %%st, %%st(1)" & NL -- X * log2 (E) +-- & "fld %%st(0) " & NL +-- & "frndint " & NL -- Integer (X * Log2 (E)) +-- & "fsubr %%st, %%st(1)" & NL -- Fraction (X * Log2 (E)) +-- & "fxch " & NL +-- & "f2xm1 " & NL -- 2**(...) - 1 +-- & "fld1 " & NL +-- & "faddp %%st, %%st(1)" & NL -- 2**(Fraction (X * Log2 (E))) +-- & "fscale " & NL -- E ** X +-- & "fstp %%st(1) ", +-- Outputs => Double'Asm_Output ("=t", Result), +-- Inputs => Double'Asm_Input ("0", X)); +-- return Result; +-- end Exp; +-- LLVM local end ------------ -- Is_Nan -- @@ -131,18 +143,20 @@ -- Log -- --------- - function Log (X : Double) return Double is - Result : Double; - - begin - Asm (Template => - "fldln2 " & NL - & "fxch " & NL - & "fyl2x " & NL, - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", X)); - return Result; - end Log; +-- LLVM local begin +-- function Log (X : Double) return Double is +-- Result : Double; +-- +-- begin +-- Asm (Template => +-- "fldln2 " & NL +-- & "fxch " & NL +-- & "fyl2x " & NL, +-- Outputs => Double'Asm_Output ("=t", Result), +-- Inputs => Double'Asm_Input ("0", X)); +-- return Result; +-- end Log; +-- LLVM local end ------------ -- Reduce -- @@ -193,6 +207,12 @@ -- Sqrt -- ---------- + -- LLVM local begin + function C_Sqrt (X : Double) return Double; + pragma Import (C, C_Sqrt, "sqrt"); + pragma Pure_Function (C_Sqrt); + -- LLVM local end + function Sqrt (X : Double) return Double is Result : Double; @@ -201,9 +221,8 @@ raise Argument_Error; end if; - Asm (Template => "fsqrt", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", X)); + -- LLVM local + Result := C_Sqrt (X); return Result; end Sqrt; @@ -214,6 +233,23 @@ -- These are built using the previously implemented basic functions + -- LLVM local begin + function C_Sin (X : Double) return Double; + pragma Import (C, C_Sin, "sin"); + pragma Pure_Function (C_Sin); + + function C_Cos (X : Double) return Double; + pragma Import (C, C_Cos, "cos"); + pragma Pure_Function (C_Cos); + + function C_Tan (X : Double) return Double; + pragma Import (C, C_Tan, "tan"); + pragma Pure_Function (C_Tan); + + procedure Sin_Cos (X : Double; Sin, Cos : out Double); + pragma Import (C, Sin_Cos, "sincos"); + -- LLVM local end + ---------- -- Acos -- ---------- @@ -267,27 +303,22 @@ case Quadrant is when 0 => - Asm (Template => "fcos", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := C_Cos (Reduced_X); when 1 => - Asm (Template => "fsin", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", -Reduced_X)); + -- LLVM local + Result := C_Sin (-Reduced_X); when 2 => - Asm (Template => "fcos ; fchs", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := -C_Cos (Reduced_X); when 3 => - Asm (Template => "fsin", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := C_Sin (Reduced_X); end case; else - Asm (Template => "fcos", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := C_Cos (Reduced_X); end if; return Result; @@ -297,26 +328,28 @@ -- Logarithmic_Pow -- --------------------- - function Logarithmic_Pow (X, Y : Double) return Double is - Result : Double; - begin - Asm (Template => "" -- X : Y - & "fyl2x " & NL -- Y * Log2 (X) - & "fst %%st(1) " & NL -- Y * Log2 (X) : Y * Log2 (X) - & "frndint " & NL -- Int (...) : Y * Log2 (X) - & "fsubr %%st, %%st(1)" & NL -- Int (...) : Fract (...) - & "fxch " & NL -- Fract (...) : Int (...) - & "f2xm1 " & NL -- 2**Fract (...) - 1 : Int (...) - & "fld1 " & NL -- 1 : 2**Fract (...) - 1 : Int (...) - & "faddp %%st, %%st(1)" & NL -- 2**Fract (...) : Int (...) - & "fscale " & NL -- 2**(Fract (...) + Int (...)) - & "fstp %%st(1) ", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => - (Double'Asm_Input ("0", X), - Double'Asm_Input ("u", Y))); - return Result; - end Logarithmic_Pow; +-- LLVM local begin +-- function Logarithmic_Pow (X, Y : Double) return Double is +-- Result : Double; +-- begin +-- Asm (Template => "" -- X : Y +-- & "fyl2x " & NL -- Y * Log2 (X) +-- & "fst %%st(1) " & NL -- Y * Log2 (X) : Y * Log2 (X) +-- & "frndint " & NL -- Int (...) : Y * Log2 (X) +-- & "fsubr %%st, %%st(1)" & NL -- Int (...) : Fract (...) +-- & "fxch " & NL -- Fract (...) : Int (...) +-- & "f2xm1 " & NL -- 2**Fract (...) - 1 : Int (...) +-- & "fld1 " & NL -- 1 : 2**Fract (...) - 1 : Int (...) +-- & "faddp %%st, %%st(1)" & NL -- 2**Fract (...) : Int (...) +-- & "fscale " & NL -- 2**(Fract (...) + Int (...)) +-- & "fstp %%st(1) ", +-- Outputs => Double'Asm_Output ("=t", Result), +-- Inputs => +-- (Double'Asm_Input ("0", X), +-- Double'Asm_Input ("u", Y))); +-- return Result; +-- end Logarithmic_Pow; +-- LLVM local end --------- -- Pow -- @@ -453,27 +486,22 @@ case Quadrant is when 0 => - Asm (Template => "fsin", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := C_Sin (Reduced_X); when 1 => - Asm (Template => "fcos", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := C_Cos (Reduced_X); when 2 => - Asm (Template => "fsin", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", -Reduced_X)); + -- LLVM local + Result := C_Sin (-Reduced_X); when 3 => - Asm (Template => "fcos ; fchs", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := -C_Cos (Reduced_X); end case; else - Asm (Template => "fsin", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := C_Sin (Reduced_X); end if; return Result; @@ -487,32 +515,26 @@ Reduced_X : Double := X; Result : Double; Quadrant : Natural range 0 .. 3; + -- LLVM local + Sin, Cos : Double; begin if abs X > Pi / 4.0 then Reduce (Reduced_X, Quadrant); if Quadrant mod 2 = 0 then - Asm (Template => "fptan" & NL - & "ffree %%st(0)" & NL - & "fincstp", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := C_Tan (Reduced_X); else - Asm (Template => "fsincos" & NL - & "fdivp %%st, %%st(1)" & NL - & "fchs", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local begin + Sin_Cos (X, Sin, Cos); + Result := -(Cos / Sin); + -- LLVM local end end if; else - Asm (Template => - "fptan " & NL - & "ffree %%st(0) " & NL - & "fincstp ", - Outputs => Double'Asm_Output ("=t", Result), - Inputs => Double'Asm_Input ("0", Reduced_X)); + -- LLVM local + Result := C_Tan (Reduced_X); end if; return Result; Modified: llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads?rev=41322&r1=41321&r2=41322&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads (original) +++ llvm-gcc-4.2/trunk/gcc/ada/a-numaux-x86.ads Thu Aug 23 11:04:48 2007 @@ -81,4 +81,11 @@ pragma Inline (Sin); pragma Inline (Sqrt); + -- LLVM local begin + pragma Import (C, Exp, "exp"); + pragma Pure_Function (Exp); + pragma Import (C, Log, "log"); + pragma Pure_Function (Log); + -- LLVM local end + end Ada.Numerics.Aux; From baldrick at free.fr Thu Aug 23 12:22:50 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 23 Aug 2007 17:22:50 -0000 Subject: [llvm-commits] [llvm] r41326 - /llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c Message-ID: <200708231722.l7NHMou1011243@zion.cs.uiuc.edu> Author: baldrick Date: Thu Aug 23 12:22:50 2007 New Revision: 41326 URL: http://llvm.org/viewvc/llvm-project?rev=41326&view=rev Log: Fix this testcase: there are two matches for llvm.cttz.i64 because of the declaration of the intrinsic. Also, emit-llvm is automatic and doesn't need to be specified. Modified: llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c Modified: llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c?rev=41326&r1=41325&r2=41326&view=diff ============================================================================== --- llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c (original) +++ llvm/trunk/test/CFrontend/2007-08-22-CTTZ.c Thu Aug 23 12:22:50 2007 @@ -1,5 +1,5 @@ -// RUN: %llvmgcc -O2 -S -o - -emit-llvm %s | grep {llvm.cttz.i64} | count 1 -// RUN: %llvmgcc -O2 -S -o - -emit-llvm %s | not grep {lshr} +// RUN: %llvmgcc -O2 -S -o - %s | grep {llvm.cttz.i64} | count 2 +// RUN: %llvmgcc -O2 -S -o - %s | not grep {lshr} int bork(unsigned long long x) { return __builtin_ctzll(x); From isanbard at gmail.com Thu Aug 23 17:07:41 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 23 Aug 2007 22:07:41 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41342 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200708232207.l7NM7f6h019693@zion.cs.uiuc.edu> Author: void Date: Thu Aug 23 17:07:41 2007 New Revision: 41342 URL: http://llvm.org/viewvc/llvm-project?rev=41342&view=rev Log: Reversing check. If a non-constant value is used, TREE_OVERFLOW barfs. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=41342&r1=41341&r2=41342&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Aug 23 17:07:41 2007 @@ -302,7 +302,7 @@ /// Always returns false for overflowed constants. bool isInt64(tree t, bool Unsigned) { if (HOST_BITS_PER_WIDE_INT == 64) - return !TREE_OVERFLOW (t) && host_integerp(t, Unsigned); + return host_integerp(t, Unsigned) && !TREE_OVERFLOW (t); else { assert(HOST_BITS_PER_WIDE_INT == 32 && "Only 32- and 64-bit hosts supported!"); From dalej at apple.com Thu Aug 23 19:56:33 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 24 Aug 2007 00:56:33 -0000 Subject: [llvm-commits] [llvm] r41348 - in /llvm/trunk: include/llvm/ADT/APFloat.h include/llvm/Constants.h lib/Support/APFloat.cpp lib/VMCore/Constants.cpp Message-ID: <200708240056.l7O0uYD0023923@zion.cs.uiuc.edu> Author: johannes Date: Thu Aug 23 19:56:33 2007 New Revision: 41348 URL: http://llvm.org/viewvc/llvm-project?rev=41348&view=rev Log: Change internal representation of ConstantFP to use APFloat. Interface to rest of the compiler unchanged, as yet. Modified: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/include/llvm/Constants.h llvm/trunk/lib/Support/APFloat.cpp llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=41348&r1=41347&r2=41348&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Thu Aug 23 19:56:33 2007 @@ -118,6 +118,9 @@ static const fltSemantics IEEEdouble; static const fltSemantics IEEEquad; static const fltSemantics x87DoubleExtended; + /* And this psuedo, used to construct APFloats that cannot + conflict with anything real. */ + static const fltSemantics Bogus; static unsigned int semanticsPrecision(const fltSemantics &); @@ -161,6 +164,8 @@ APFloat(const fltSemantics &, const char *); APFloat(const fltSemantics &, integerPart); APFloat(const fltSemantics &, fltCategory, bool negative); + APFloat(double d); + APFloat(float f); APFloat(const APFloat &); ~APFloat(); @@ -179,10 +184,16 @@ opStatus convertFromInteger(const integerPart *, unsigned int, bool, roundingMode); opStatus convertFromString(const char *, roundingMode); + double convertToDouble() const; + float convertToFloat() const; - /* Comparison with another floating point number. */ + /* IEEE comparison with another floating point number (QNaNs + compare unordered, 0==-0). */ cmpResult compare(const APFloat &) const; + /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */ + bool operator==(const APFloat &) const; + /* Simple queries. */ fltCategory getCategory() const { return category; } const fltSemantics &getSemantics() const { return *semantics; } @@ -192,6 +203,9 @@ APFloat& operator=(const APFloat &); + /* Return an arbitrary integer value usable for hashing. */ + uint32_t getHashValue() const; + private: /* Trivial queries. */ Modified: llvm/trunk/include/llvm/Constants.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=41348&r1=41347&r2=41348&view=diff ============================================================================== --- llvm/trunk/include/llvm/Constants.h (original) +++ llvm/trunk/include/llvm/Constants.h Thu Aug 23 19:56:33 2007 @@ -23,6 +23,7 @@ #include "llvm/Constant.h" #include "llvm/Type.h" #include "llvm/ADT/APInt.h" +#include "llvm/ADT/APFloat.h" namespace llvm { @@ -213,7 +214,7 @@ /// ConstantFP - Floating Point Values [float, double] /// class ConstantFP : public Constant { - double Val; + APFloat Val; ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT protected: ConstantFP(const Type *Ty, double V); @@ -223,7 +224,14 @@ /// isValueValidForType - return true if Ty is big enough to represent V. static bool isValueValidForType(const Type *Ty, double V); - inline double getValue() const { return Val; } + inline double getValue() const { + if (&Val.getSemantics() == &APFloat::IEEEdouble) + return Val.convertToDouble(); + else if (&Val.getSemantics() == &APFloat::IEEEsingle) + return (double)Val.convertToFloat(); + else + assert(0); + } /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. Don't depend on == for doubles to tell us it's zero, it Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=41348&r1=41347&r2=41348&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Thu Aug 23 19:56:33 2007 @@ -46,6 +46,7 @@ const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true }; const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true }; const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, false }; + const fltSemantics APFloat::Bogus = { 0, 0, 0, false }; } /* Put a bunch of private, handy routines in an anonymous namespace. */ @@ -273,6 +274,31 @@ return *this; } +bool +APFloat::operator==(const APFloat &rhs) const { + if (this == &rhs) + return true; + if (semantics != rhs.semantics || + category != rhs.category) + return false; + if (category==fcQNaN) + return true; + else if (category==fcZero || category==fcInfinity) + return sign==rhs.sign; + else { + if (sign!=rhs.sign || exponent!=rhs.exponent) + return false; + int i= partCount(); + const integerPart* p=significandParts(); + const integerPart* q=rhs.significandParts(); + for (; i>0; i--, p++, q++) { + if (*p != *q) + return false; + } + return true; + } +} + APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) { initialize(&ourSemantics); @@ -1482,7 +1508,167 @@ return convertFromHexadecimalString(p + 2, rounding_mode); else { - assert(0 && "Decimal to binary conversions not yet imlemented"); + assert(0 && "Decimal to binary conversions not yet implemented"); abort(); } } + +// For good performance it is desirable for different APFloats +// to produce different integers. +uint32_t +APFloat::getHashValue() const { + if (category==fcZero) return sign<<8 | semantics->precision ; + else if (category==fcInfinity) return sign<<9 | semantics->precision; + else if (category==fcQNaN) return 1<<10 | semantics->precision; + else { + uint32_t hash = sign<<11 | semantics->precision | exponent<<12; + const integerPart* p = significandParts(); + for (int i=partCount(); i>0; i--, p++) + hash ^= ((uint32_t)*p) ^ (*p)>>32; + return hash; + } +} + +// Conversion from APFloat to/from host float/double. It may eventually be +// possible to eliminate these and have everybody deal with APFloats, but that +// will take a while. This approach will not easily extend to long double. +// Current implementation requires partCount()==1, which is correct at the +// moment but could be made more general. + +double +APFloat::convertToDouble() const { + union { + double d; + uint64_t i; + } u; + assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble); + assert (partCount()==1); + + uint64_t myexponent, mysign, mysignificand; + + if (category==fcNormal) { + mysign = sign; + mysignificand = *significandParts(); + myexponent = exponent+1023; //bias + } else if (category==fcZero) { + mysign = sign; + myexponent = 0; + mysignificand = 0; + } else if (category==fcInfinity) { + mysign = sign; + myexponent = 0x7ff; + mysignificand = 0; + } else if (category==fcQNaN) { + mysign = 0; + myexponent = 0x7ff; + mysignificand = 0xfffffffffffffLL; + } else + assert(0); + + u.i = ((mysign & 1) << 63) | ((myexponent & 0x7ff) << 52) | + (mysignificand & 0xfffffffffffffLL); + return u.d; +} + +float +APFloat::convertToFloat() const { + union { + float f; + int32_t i; + } u; + assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle); + assert (partCount()==1); + + uint32_t mysign, myexponent, mysignificand; + + if (category==fcNormal) { + mysign = sign; + myexponent = exponent+127; //bias + mysignificand = *significandParts(); + } else if (category==fcZero) { + mysign = sign; + myexponent = 0; + mysignificand = 0; + } else if (category==fcInfinity) { + mysign = sign; + myexponent = 0xff; + mysignificand = 0; + } else if (category==fcQNaN) { + mysign = sign; + myexponent = 0x7ff; + mysignificand = 0x7fffff; + } else + assert(0); + + u.i = ((mysign&1) << 31) | ((myexponent&0xff) << 23) | + ((mysignificand & 0x7fffff)); + return u.f; +} + +APFloat::APFloat(double d) { + initialize(&APFloat::IEEEdouble); + union { + double d; + uint64_t i; + } u; + u.d = d; + assert(partCount()==1); + + uint64_t mysign, myexponent, mysignificand; + + mysign = u.i >> 63; + myexponent = (u.i >> 52) & 0x7ff; + mysignificand = u.i & 0xfffffffffffffLL; + + if (myexponent==0 && mysignificand==0) { + // exponent, significand meaningless + category = fcZero; + sign = mysign; + } else if (myexponent==0x7ff && mysignificand==0) { + // exponent, significand meaningless + category = fcInfinity; + sign = mysign; + } else if (myexponent==0x7ff && (mysignificand & 0x8000000000000LL)) { + // sign, exponent, significand meaningless + category = fcQNaN; + } else { + sign = mysign; + category = fcNormal; + exponent = myexponent - 1023; + *significandParts() = mysignificand | 0x100000000000000LL; + } +} + +APFloat::APFloat(float f) { + initialize(&APFloat::IEEEsingle); + union { + float f; + uint32_t i; + } u; + u.f = f; + assert(partCount()==1); + + uint32_t mysign, myexponent, mysignificand; + + mysign = u.i >> 31; + myexponent = (u.i >> 23) & 0xff; + mysignificand = u.i & 0x7fffff; + + if (myexponent==0 && mysignificand==0) { + // exponent, significand meaningless + category = fcZero; + sign = mysign; + } else if (myexponent==0xff && mysignificand==0) { + // exponent, significand meaningless + category = fcInfinity; + sign = mysign; + } else if (myexponent==0xff && (mysignificand & 0x400000)) { + // sign, exponent, significand meaningless + category = fcQNaN; + } else { + category = fcNormal; + sign = mysign; + exponent = myexponent - 127; //bias + *significandParts() = mysignificand | 0x800000; // integer bit + } +} Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=41348&r1=41347&r2=41348&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Thu Aug 23 19:56:33 2007 @@ -202,7 +202,7 @@ return DenseMapKeyInfo::getHashValue(Key.type) ^ Key.val.getHashValue(); } - static bool isPod() { return true; } + static bool isPod() { return false; } }; } @@ -240,63 +240,63 @@ ConstantFP::ConstantFP(const Type *Ty, double V) - : Constant(Ty, ConstantFPVal, 0, 0) { - Val = V; + : Constant(Ty, ConstantFPVal, 0, 0), Val(APFloat(V)) { } bool ConstantFP::isNullValue() const { - return DoubleToBits(Val) == 0; + return Val.isZero() && !Val.isNegative(); } bool ConstantFP::isExactlyValue(double V) const { - return DoubleToBits(V) == DoubleToBits(Val); + return Val == APFloat(V); } - namespace { - struct DenseMapInt64KeyInfo { - typedef std::pair KeyTy; - static inline KeyTy getEmptyKey() { return KeyTy(0, 0); } - static inline KeyTy getTombstoneKey() { return KeyTy(1, 0); } - static unsigned getHashValue(const KeyTy &Key) { - return DenseMapKeyInfo::getHashValue(Key.second) ^ Key.first; + struct DenseMapAPFloatKeyInfo { + struct KeyTy { + APFloat val; + KeyTy(const APFloat& V) : val(V){} + KeyTy(const KeyTy& that) : val(that.val) {} + bool operator==(const KeyTy& that) const { + return this->val == that.val; + } + bool operator!=(const KeyTy& that) const { + return !this->operator==(that); + } + }; + static inline KeyTy getEmptyKey() { + return KeyTy(APFloat(APFloat::Bogus,1)); + } + static inline KeyTy getTombstoneKey() { + return KeyTy(APFloat(APFloat::Bogus,2)); } - static bool isPod() { return true; } - }; - struct DenseMapInt32KeyInfo { - typedef std::pair KeyTy; - static inline KeyTy getEmptyKey() { return KeyTy(0, 0); } - static inline KeyTy getTombstoneKey() { return KeyTy(1, 0); } static unsigned getHashValue(const KeyTy &Key) { - return DenseMapKeyInfo::getHashValue(Key.second) ^ Key.first; + return Key.val.getHashValue(); } - static bool isPod() { return true; } + static bool isPod() { return false; } }; } //---- ConstantFP::get() implementation... // -typedef DenseMap FloatMapTy; -typedef DenseMap DoubleMapTy; +typedef DenseMap FPMapTy; -static ManagedStatic FloatConstants; -static ManagedStatic DoubleConstants; +static ManagedStatic FPConstants; ConstantFP *ConstantFP::get(const Type *Ty, double V) { if (Ty == Type::FloatTy) { - uint32_t IntVal = FloatToBits((float)V); - - ConstantFP *&Slot = (*FloatConstants)[std::make_pair(IntVal, Ty)]; + DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((float)V)); + ConstantFP *&Slot = (*FPConstants)[Key]; if (Slot) return Slot; return Slot = new ConstantFP(Ty, (float)V); - } else if (Ty == Type::DoubleTy) { - uint64_t IntVal = DoubleToBits(V); - ConstantFP *&Slot = (*DoubleConstants)[std::make_pair(IntVal, Ty)]; + } else if (Ty == Type::DoubleTy) { + // Without the redundant cast, the following is taken to be + // a function declaration. What a language. + DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((double)V)); + ConstantFP *&Slot = (*FPConstants)[Key]; if (Slot) return Slot; return Slot = new ConstantFP(Ty, V); - // FIXME: Make long double constants work. } else if (Ty == Type::X86_FP80Ty || Ty == Type::PPC_FP128Ty || Ty == Type::FP128Ty) { assert(0 && "Long double constants not handled yet."); From alenhar2 at cs.uiuc.edu Thu Aug 23 21:57:58 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 24 Aug 2007 02:57:58 -0000 Subject: [llvm-commits] [poolalloc] r41351 - in /poolalloc/trunk/lib/DSA: BottomUpClosure.cpp CallTargets.cpp CompleteBottomUp.cpp DataStructureAA.cpp DataStructureOpt.cpp DataStructureStats.cpp EquivClassGraphs.cpp GraphChecker.cpp Local.cpp StdLibPass.cpp Steensgaard.cpp TopDownClosure.cpp Message-ID: <200708240257.l7O2vwin026902@zion.cs.uiuc.edu> Author: alenhar2 Date: Thu Aug 23 21:57:58 2007 New Revision: 41351 URL: http://llvm.org/viewvc/llvm-project?rev=41351&view=rev Log: forgot to commit this Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp poolalloc/trunk/lib/DSA/CallTargets.cpp poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp poolalloc/trunk/lib/DSA/DataStructureAA.cpp poolalloc/trunk/lib/DSA/DataStructureOpt.cpp poolalloc/trunk/lib/DSA/DataStructureStats.cpp poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp poolalloc/trunk/lib/DSA/GraphChecker.cpp poolalloc/trunk/lib/DSA/Local.cpp poolalloc/trunk/lib/DSA/StdLibPass.cpp poolalloc/trunk/lib/DSA/Steensgaard.cpp poolalloc/trunk/lib/DSA/TopDownClosure.cpp Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original) +++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Thu Aug 23 21:57:58 2007 @@ -34,6 +34,8 @@ X("dsa-bu", "Bottom-up Data Structure Analysis"); } +char BUDataStructures::ID; + // run - Calculate the bottom up data structure graphs for each function in the // program. // Modified: poolalloc/trunk/lib/DSA/CallTargets.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CallTargets.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/CallTargets.cpp (original) +++ poolalloc/trunk/lib/DSA/CallTargets.cpp Thu Aug 23 21:57:58 2007 @@ -38,6 +38,8 @@ RegisterPass X("calltarget","Find Call Targets (uses DSA)"); } +char CallTargetFinder::ID; + void CallTargetFinder::findIndTargets(Module &M) { TDDataStructures* T = &getAnalysis(); Modified: poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp (original) +++ poolalloc/trunk/lib/DSA/CompleteBottomUp.cpp Thu Aug 23 21:57:58 2007 @@ -29,6 +29,7 @@ STATISTIC (NumCBUInlines, "Number of graphs inlined"); } +char CompleteBUDataStructures::ID; // run - Calculate the bottom up data structure graphs for each function in the // program. Modified: poolalloc/trunk/lib/DSA/DataStructureAA.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructureAA.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DataStructureAA.cpp (original) +++ poolalloc/trunk/lib/DSA/DataStructureAA.cpp Thu Aug 23 21:57:58 2007 @@ -104,6 +104,8 @@ RegisterAnalysisGroup Y(X); } +char DSAA::ID; + ModulePass *llvm::createDSAAPass() { return new DSAA(); } // getGraphForValue - Return the DSGraph to use for queries about the specified Modified: poolalloc/trunk/lib/DSA/DataStructureOpt.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructureOpt.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DataStructureOpt.cpp (original) +++ poolalloc/trunk/lib/DSA/DataStructureOpt.cpp Thu Aug 23 21:57:58 2007 @@ -52,6 +52,8 @@ RegisterPass X("ds-opt", "DSA-based simple optimizations"); } +char DSOpt::ID; + ModulePass *llvm::createDSOptPass() { return new DSOpt(); } /// OptimizeGlobals - This method uses information taken from DSA to optimize Modified: poolalloc/trunk/lib/DSA/DataStructureStats.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructureStats.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/DataStructureStats.cpp (original) +++ poolalloc/trunk/lib/DSA/DataStructureStats.cpp Thu Aug 23 21:57:58 2007 @@ -65,6 +65,8 @@ static RegisterPass Z("dsstats", "DS Graph Statistics"); } +char DSGraphStats::ID; + FunctionPass *llvm::createDataStructureStatsPass() { return new DSGraphStats(); } Modified: poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp (original) +++ poolalloc/trunk/lib/DSA/EquivClassGraphs.cpp Thu Aug 23 21:57:58 2007 @@ -37,6 +37,8 @@ "Number of graphs inlined"); } +char EquivClassGraphs::ID; + #ifndef NDEBUG template static void CheckAllGraphs(Module *M, GT &ECGraphs) { Modified: poolalloc/trunk/lib/DSA/GraphChecker.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/GraphChecker.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/GraphChecker.cpp (original) +++ poolalloc/trunk/lib/DSA/GraphChecker.cpp Thu Aug 23 21:57:58 2007 @@ -77,6 +77,8 @@ RegisterPass X("datastructure-gc", "DSA Graph Checking Pass"); } +char DSGC::ID; + FunctionPass *llvm::createDataStructureGraphCheckerPass() { return new DSGC(); } Modified: poolalloc/trunk/lib/DSA/Local.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/Local.cpp (original) +++ poolalloc/trunk/lib/DSA/Local.cpp Thu Aug 23 21:57:58 2007 @@ -64,7 +64,7 @@ //////////////////////////////////////////////////////////////////////////// // Helper functions used to implement the visitation functions... - void MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C); + void MergeConstantInitIntoNode(DSNodeHandle &NH, const Type* Ty, Constant *C); /// createNode - Create a new DSNode, ensuring that it is properly added to /// the graph. @@ -297,6 +297,8 @@ void GraphBuilder::visitLoadInst(LoadInst &LI) { DSNodeHandle Ptr = getValueDest(*LI.getOperand(0)); + if (Ptr.isNull()) return; // Load from null + // Make that the node is read from... Ptr.getNode()->setReadMarker(); @@ -345,6 +347,8 @@ } void GraphBuilder::visitIntToPtrInst(IntToPtrInst &I) { + std::cerr << "cast in " << I.getParent()->getParent()->getName() << "\n"; + I.dump(); setDestTo(I, createNode()->setUnknownMarker()->setIntToPtrMarker()); } @@ -659,13 +663,13 @@ // MergeConstantInitIntoNode - Merge the specified constant into the node // pointed to by NH. -void GraphBuilder::MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C) { +void GraphBuilder::MergeConstantInitIntoNode(DSNodeHandle &NH, const Type* Ty, Constant *C) { // Ensure a type-record exists... DSNode *NHN = NH.getNode(); - NHN->mergeTypeInfo(C->getType(), NH.getOffset()); + NHN->mergeTypeInfo(Ty, NH.getOffset()); - if (C->getType()->isFirstClassType()) { - if (isa(C->getType())) + if (Ty->isFirstClassType()) { + if (isa(Ty)) // Avoid adding edges from null, or processing non-"pointer" stores NH.addEdgeTo(getValueDest(*C)); return; @@ -676,15 +680,15 @@ if (ConstantArray *CA = dyn_cast(C)) { for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) // We don't currently do any indexing for arrays... - MergeConstantInitIntoNode(NH, cast(CA->getOperand(i))); + MergeConstantInitIntoNode(NH, cast(Ty)->getElementType(), cast(CA->getOperand(i))); } else if (ConstantStruct *CS = dyn_cast(C)) { - const StructLayout *SL = TD.getStructLayout(CS->getType()); + const StructLayout *SL = TD.getStructLayout(cast(Ty)); for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) { DSNode *NHN = NH.getNode(); //Some programmers think ending a structure with a [0 x sbyte] is cute if (SL->getElementOffset(i) < SL->getSizeInBytes()) { DSNodeHandle NewNH(NHN, NH.getOffset()+(unsigned)SL->getElementOffset(i)); - MergeConstantInitIntoNode(NewNH, cast(CS->getOperand(i))); + MergeConstantInitIntoNode(NewNH, cast(Ty)->getElementType(i), cast(CS->getOperand(i))); } else if (SL->getElementOffset(i) == SL->getSizeInBytes()) { DOUT << "Zero size element at end of struct\n"; NHN->foldNodeCompletely(); @@ -703,9 +707,10 @@ assert(!GV->isDeclaration() && "Cannot merge in external global!"); // Get a node handle to the global node and merge the initializer into it. DSNodeHandle NH = getValueDest(*GV); - MergeConstantInitIntoNode(NH, GV->getInitializer()); + MergeConstantInitIntoNode(NH, GV->getType()->getElementType(), GV->getInitializer()); } +char LocalDataStructures::ID; bool LocalDataStructures::runOnModule(Module &M) { setTargetData(getAnalysis()); Modified: poolalloc/trunk/lib/DSA/StdLibPass.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/StdLibPass.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/StdLibPass.cpp (original) +++ poolalloc/trunk/lib/DSA/StdLibPass.cpp Thu Aug 23 21:57:58 2007 @@ -29,6 +29,8 @@ static RegisterPass X("dsa-stdlib", "Standard Library Local Data Structure Analysis"); +char StdLibDataStructures::ID; + bool StdLibDataStructures::runOnModule(Module &M) { LocalDataStructures &LocalDSA = getAnalysis(); setGraphSource(&LocalDSA); Modified: poolalloc/trunk/lib/DSA/Steensgaard.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Steensgaard.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/Steensgaard.cpp (original) +++ poolalloc/trunk/lib/DSA/Steensgaard.cpp Thu Aug 23 21:57:58 2007 @@ -85,6 +85,8 @@ RegisterAnalysisGroup Y(X); } +char Steens::ID; + ModulePass *llvm::createSteensgaardPass() { return new Steens(); } /// ResolveFunctionCall - Resolve the actual arguments of a call to function F Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=41351&r1=41350&r2=41351&view=diff ============================================================================== --- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original) +++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Thu Aug 23 21:57:58 2007 @@ -38,6 +38,8 @@ STATISTIC (NumTDInlines, "Number of graphs inlined"); } +char TDDataStructures::ID; + void TDDataStructures::markReachableFunctionsExternallyAccessible(DSNode *N, hash_set &Visited) { if (!N || Visited.count(N)) return; From sabre at nondot.org Thu Aug 23 22:02:35 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 24 Aug 2007 03:02:35 -0000 Subject: [llvm-commits] [llvm] r41352 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200708240302.l7O32Zvm027028@zion.cs.uiuc.edu> Author: lattner Date: Thu Aug 23 22:02:34 2007 New Revision: 41352 URL: http://llvm.org/viewvc/llvm-project?rev=41352&view=rev Log: silence some warnings in an optimized build. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=41352&r1=41351&r2=41352&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Thu Aug 23 22:02:34 2007 @@ -915,20 +915,20 @@ APFloat temp_rhs(rhs); bool reverse; - if(bits == 0) { + if (bits == 0) { reverse = compareAbsoluteValue(temp_rhs) == cmpLessThan; lost_fraction = lfExactlyZero; - } else if(bits > 0) { + } else if (bits > 0) { lost_fraction = temp_rhs.shiftSignificandRight(bits - 1); shiftSignificandLeft(1); reverse = false; - } else if(bits < 0) { + } else { lost_fraction = shiftSignificandRight(-bits - 1); temp_rhs.shiftSignificandLeft(1); reverse = true; } - if(reverse) { + if (reverse) { carry = temp_rhs.subtractSignificand (*this, lost_fraction != lfExactlyZero); copySignificand(temp_rhs); @@ -1496,8 +1496,7 @@ } APFloat::opStatus -APFloat::convertFromString(const char *p, roundingMode rounding_mode) -{ +APFloat::convertFromString(const char *p, roundingMode rounding_mode) { /* Handle a leading minus sign. */ if(*p == '-') sign = 1, p++; @@ -1506,11 +1505,9 @@ if(p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) return convertFromHexadecimalString(p + 2, rounding_mode); - else - { - assert(0 && "Decimal to binary conversions not yet implemented"); - abort(); - } + + assert(0 && "Decimal to binary conversions not yet implemented"); + abort(); } // For good performance it is desirable for different APFloats From clattner at apple.com Thu Aug 23 22:05:01 2007 From: clattner at apple.com (Chris Lattner) Date: Thu, 23 Aug 2007 20:05:01 -0700 Subject: [llvm-commits] [llvm] r40549 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ include/llvm/Target/ lib/AsmParser/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/VMCore/ In-Reply-To: <200708230157.04393.baldrick@free.fr> References: <200707271258.l6RCwus3032767@zion.cs.uiuc.edu> <200708230157.04393.baldrick@free.fr> Message-ID: On Aug 22, 2007, at 4:57 PM, Duncan Sands wrote: > Hi Chris, > >> Nice summary. Dummy question: it isn't possible to merge the init >> and adjust intrinsics, is it? If the result of init can only be used >> by adjust, it seems reasonable to merge them. > > yes they can be merged, but that would require some gcc hacking (not > trivial, but not hard either). The reason is that gcc currently > stores > the memory for the trampoline in the frame object that gets passed > around to nested functions. When a nested functions wants to call > the trampoline, it takes the address of this memory from the object > it was > passed and calls adjust_trampoline on it - this can happen far away > from the > trampoline initialization. What would need to be done is to move > the memory > out of the frame object and into an alloca, and store a function > pointer > inside the frame object instead. init_trampoline would then > initialize the > trampoline memory and generate the function pointer, which would > then be > stored in the frame object. Shall I do it? As we discussed, I think following GCC's model is fine. >>> +SDOperand ARMTargetLowering::LowerADJUST_TRAMP(SDOperand Op, >>> + SelectionDAG >>> &DAG) { >>> + // Thumb trampolines should be entered in thumb mode, so set the >>> bottom bit >>> + // of the address. >>> + return DAG.getNode(ISD::OR, MVT::i32, Op.getOperand(0), >>> + DAG.getConstant(1, MVT::i32)); >> >> This may or may not be right in the future. For now, both GCC and >> LLVM compile an entire file in thumb or in arm mode. In the future, >> we may mix and match functions as appropriate. Can you please add a >> fixme to this saying that we should reevaluate it if the caller and >> callee can ever be different ISAs. > > I don't know anything about ARM or thumb, but I think the reason is > that > the trampoline itself (i.e. the code on the stack) is written in thumb > mode (remember that this is a canned sequence of instructions that are > not generated by LLVM itself), and thus should be called via a pointer > with the bottom bit set. The nested function itself, the code for > which > is generated by LLVM, can presumably be in thumb mode or not, and will > have the mode encoded in the lower bit of its address in the usual > way; > when the trampoline jumps to it, the correct new mode should be set > appropriately. So I don't see any problem here, assuming we copy the > trampoline initializer from gcc (where it is a bunch of thumb mode > opcodes). Ahhh, ok! -Chris From dalej at apple.com Fri Aug 24 00:08:12 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 24 Aug 2007 05:08:12 -0000 Subject: [llvm-commits] [llvm] r41353 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/Support/APFloat.cpp lib/VMCore/Constants.cpp Message-ID: <200708240508.l7O58CFI030811@zion.cs.uiuc.edu> Author: johannes Date: Fri Aug 24 00:08:11 2007 New Revision: 41353 URL: http://llvm.org/viewvc/llvm-project?rev=41353&view=rev Log: Revised per review feedback from previous patch. Modified: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/lib/Support/APFloat.cpp llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=41353&r1=41352&r2=41353&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Fri Aug 24 00:08:11 2007 @@ -194,6 +194,11 @@ /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */ bool operator==(const APFloat &) const; + /* Inversion of the preceding. */ + inline bool operator!=(const APFloat &RHS) const { + return !((*this)==RHS); + } + /* Simple queries. */ fltCategory getCategory() const { return category; } const fltSemantics &getSemantics() const { return *semantics; } Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=41353&r1=41352&r2=41353&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Fri Aug 24 00:08:11 2007 @@ -14,6 +14,7 @@ #include #include "llvm/ADT/APFloat.h" +#include "llvm/Support/MathExtras.h" using namespace llvm; @@ -1534,10 +1535,6 @@ double APFloat::convertToDouble() const { - union { - double d; - uint64_t i; - } u; assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble); assert (partCount()==1); @@ -1562,17 +1559,12 @@ } else assert(0); - u.i = ((mysign & 1) << 63) | ((myexponent & 0x7ff) << 52) | - (mysignificand & 0xfffffffffffffLL); - return u.d; + return BitsToDouble(((mysign & 1) << 63) | ((myexponent & 0x7ff) << 52) | + (mysignificand & 0xfffffffffffffLL)); } float APFloat::convertToFloat() const { - union { - float f; - int32_t i; - } u; assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle); assert (partCount()==1); @@ -1597,26 +1589,19 @@ } else assert(0); - u.i = ((mysign&1) << 31) | ((myexponent&0xff) << 23) | - ((mysignificand & 0x7fffff)); - return u.f; + return BitsToFloat(((mysign&1) << 31) | ((myexponent&0xff) << 23) | + (mysignificand & 0x7fffff)); } APFloat::APFloat(double d) { + uint64_t i = DoubleToBits(d); + uint64_t mysign = i >> 63; + uint64_t myexponent = (i >> 52) & 0x7ff; + uint64_t mysignificand = i & 0xfffffffffffffLL; + initialize(&APFloat::IEEEdouble); - union { - double d; - uint64_t i; - } u; - u.d = d; assert(partCount()==1); - uint64_t mysign, myexponent, mysignificand; - - mysign = u.i >> 63; - myexponent = (u.i >> 52) & 0x7ff; - mysignificand = u.i & 0xfffffffffffffLL; - if (myexponent==0 && mysignificand==0) { // exponent, significand meaningless category = fcZero; @@ -1637,20 +1622,14 @@ } APFloat::APFloat(float f) { + uint32_t i = FloatToBits(f); + uint32_t mysign = i >> 31; + uint32_t myexponent = (i >> 23) & 0xff; + uint32_t mysignificand = i & 0x7fffff; + initialize(&APFloat::IEEEsingle); - union { - float f; - uint32_t i; - } u; - u.f = f; assert(partCount()==1); - uint32_t mysign, myexponent, mysignificand; - - mysign = u.i >> 31; - myexponent = (u.i >> 23) & 0xff; - mysignificand = u.i & 0x7fffff; - if (myexponent==0 && mysignificand==0) { // exponent, significand meaningless category = fcZero; Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=41353&r1=41352&r2=41353&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Fri Aug 24 00:08:11 2007 @@ -253,25 +253,14 @@ namespace { struct DenseMapAPFloatKeyInfo { - struct KeyTy { - APFloat val; - KeyTy(const APFloat& V) : val(V){} - KeyTy(const KeyTy& that) : val(that.val) {} - bool operator==(const KeyTy& that) const { - return this->val == that.val; - } - bool operator!=(const KeyTy& that) const { - return !this->operator==(that); - } - }; - static inline KeyTy getEmptyKey() { - return KeyTy(APFloat(APFloat::Bogus,1)); + static inline APFloat getEmptyKey() { + return APFloat(APFloat::Bogus,1); } - static inline KeyTy getTombstoneKey() { - return KeyTy(APFloat(APFloat::Bogus,2)); + static inline APFloat getTombstoneKey() { + return APFloat(APFloat::Bogus,2); } - static unsigned getHashValue(const KeyTy &Key) { - return Key.val.getHashValue(); + static unsigned getHashValue(const APFloat &Key) { + return Key.getHashValue(); } static bool isPod() { return false; } }; @@ -279,21 +268,21 @@ //---- ConstantFP::get() implementation... // -typedef DenseMap FPMapTy; static ManagedStatic FPConstants; ConstantFP *ConstantFP::get(const Type *Ty, double V) { if (Ty == Type::FloatTy) { - DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((float)V)); + APFloat Key(APFloat((float)V)); ConstantFP *&Slot = (*FPConstants)[Key]; if (Slot) return Slot; return Slot = new ConstantFP(Ty, (float)V); } else if (Ty == Type::DoubleTy) { // Without the redundant cast, the following is taken to be // a function declaration. What a language. - DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((double)V)); + APFloat Key(APFloat((double)V)); ConstantFP *&Slot = (*FPConstants)[Key]; if (Slot) return Slot; return Slot = new ConstantFP(Ty, V); From dpatel at apple.com Fri Aug 24 00:21:13 2007 From: dpatel at apple.com (Devang Patel) Date: Fri, 24 Aug 2007 05:21:13 -0000 Subject: [llvm-commits] [llvm] r41354 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708240521.l7O5LDs8031218@zion.cs.uiuc.edu> Author: dpatel Date: Fri Aug 24 00:21:13 2007 New Revision: 41354 URL: http://llvm.org/viewvc/llvm-project?rev=41354&view=rev Log: Remove incomplete cost analysis. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41354&r1=41353&r2=41354&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 00:21:13 2007 @@ -103,9 +103,6 @@ /// DeadBB. LiveBB dominates split conidition's other branch. void removeBlocks(BasicBlock *DeadBB, Loop *LP, BasicBlock *LiveBB); - /// Find cost of spliting loop L. - unsigned findSplitCost(Loop *L, SplitInfo &SD); - /// safeSplitCondition - Return true if it is possible to /// split loop using given split condition. bool safeSplitCondition(SplitInfo &SD); @@ -202,25 +199,10 @@ ++SI; } - unsigned MaxCost = 99; - unsigned Index = 0; - unsigned MostProfitableSDIndex = 0; - for (SmallVector::iterator SI = SplitData.begin(), - E = SplitData.end(); SI != E; ++SI, ++Index) { - SplitInfo SD = *SI; - - // ICM_EQs are already handled above. - assert (SD.SplitCondition->getPredicate() != ICmpInst::ICMP_EQ && - "Unexpected split condition predicate"); - - unsigned Cost = findSplitCost(L, SD); - if (Cost < MaxCost) - MostProfitableSDIndex = Index; - } - // Split most profitiable condition. - if (!SplitData.empty()) - Changed = splitLoop(SplitData[MostProfitableSDIndex]); + // FIXME : Implement cost analysis. + unsigned MostProfitableSDIndex = 0; + Changed = splitLoop(SplitData[MostProfitableSDIndex]); if (Changed) ++NumIndexSplit; @@ -595,25 +577,6 @@ return true; } -/// Find cost of spliting loop L. Cost is measured in terms of size growth. -/// Size is growth is calculated based on amount of code duplicated in second -/// loop. -unsigned LoopIndexSplit::findSplitCost(Loop *L, SplitInfo &SD) { - - unsigned Cost = 0; - BasicBlock *SDBlock = SD.SplitCondition->getParent(); - for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); - I != E; ++I) { - BasicBlock *BB = *I; - // If a block is not dominated by split condition block then - // it must be duplicated in both loops. - if (!DT->dominates(SDBlock, BB)) - Cost += BB->size(); - } - - return Cost; -} - /// removeBlocks - Remove basic block DeadBB and all blocks dominated by DeadBB. /// This routine is used to remove split condition's dead branch, dominated by /// DeadBB. LiveBB dominates split conidition's other branch. From dpatel at apple.com Fri Aug 24 00:36:57 2007 From: dpatel at apple.com (Devang Patel) Date: Fri, 24 Aug 2007 05:36:57 -0000 Subject: [llvm-commits] [llvm] r41356 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708240536.l7O5av4B031824@zion.cs.uiuc.edu> Author: dpatel Date: Fri Aug 24 00:36:56 2007 New Revision: 41356 URL: http://llvm.org/viewvc/llvm-project?rev=41356&view=rev Log: Tightenup loop filter. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41356&r1=41355&r2=41356&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 00:36:56 2007 @@ -272,7 +272,12 @@ if (!ExitingBlock) return; - + + // If exiting block is neither loop header nor loop latch then this loop is + // not suitable. + if (ExitingBlock != L->getHeader() && ExitingBlock != L->getLoopLatch()) + return; + // If exit block's terminator is conditional branch inst then we have found // exit condition. BranchInst *BR = dyn_cast(ExitingBlock->getTerminator()); @@ -705,7 +710,22 @@ if (Succ0 == *PI) return false; - return true; + // Finally this split condition is safe only if merge point for + // split condition branch is loop latch. This check along with previous + // check, to ensure that exit condition is in either loop latch or header, + // filters all loops with non-empty loop body between merge point + // and exit condition. + DominanceFrontier::iterator Succ0DF = DF->find(Succ0); + assert (Succ0DF != DF->end() && "Unable to find Succ0 dominance frontier"); + if (Succ0DF->second.count(Latch)) + return true; + + DominanceFrontier::iterator Succ1DF = DF->find(Succ1); + assert (Succ1DF != DF->end() && "Unable to find Succ1 dominance frontier"); + if (Succ1DF->second.count(Latch)) + return true; + + return false; } /// splitLoop - Split current loop L in two loops using split information From dpatel at apple.com Fri Aug 24 01:02:26 2007 From: dpatel at apple.com (Devang Patel) Date: Fri, 24 Aug 2007 06:02:26 -0000 Subject: [llvm-commits] [llvm] r41357 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708240602.l7O62QAM032483@zion.cs.uiuc.edu> Author: dpatel Date: Fri Aug 24 01:02:25 2007 New Revision: 41357 URL: http://llvm.org/viewvc/llvm-project?rev=41357&view=rev Log: Reject ICMP_NE as index split condition. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41357&r1=41356&r2=41357&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 01:02:25 2007 @@ -338,6 +338,9 @@ if (!CI || CI == ExitCondition) return; + if (CI->getPredicate() == ICmpInst::ICMP_NE) + return; + // If one operand is loop invariant and second operand is SCEVAddRecExpr // based on induction variable then CI is a candidate split condition. Value *V0 = CI->getOperand(0); From dpatel at apple.com Fri Aug 24 01:17:19 2007 From: dpatel at apple.com (Devang Patel) Date: Fri, 24 Aug 2007 06:17:19 -0000 Subject: [llvm-commits] [llvm] r41358 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708240617.l7O6HJB0000593@zion.cs.uiuc.edu> Author: dpatel Date: Fri Aug 24 01:17:19 2007 New Revision: 41358 URL: http://llvm.org/viewvc/llvm-project?rev=41358&view=rev Log: It is not safe to execute split condition's true branch first all the time. If split condition predicate is GT or GE then execute false branch first. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41358&r1=41357&r2=41358&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 01:17:19 2007 @@ -57,7 +57,8 @@ class SplitInfo { public: - SplitInfo() : SplitValue(NULL), SplitCondition(NULL) {} + SplitInfo() : SplitValue(NULL), SplitCondition(NULL), + UseTrueBranchFirst(true) {} // Induction variable's range is split at this value. Value *SplitValue; @@ -65,10 +66,14 @@ // This compare instruction compares IndVar against SplitValue. ICmpInst *SplitCondition; + // True if after loop index split, first loop will execute split condition's + // true branch. + bool UseTrueBranchFirst; // Clear split info. void clear() { SplitValue = NULL; SplitCondition = NULL; + UseTrueBranchFirst = true; } }; @@ -199,6 +204,9 @@ ++SI; } + if (SplitData.empty()) + return false; + // Split most profitiable condition. // FIXME : Implement cost analysis. unsigned MostProfitableSDIndex = 0; @@ -341,6 +349,14 @@ if (CI->getPredicate() == ICmpInst::ICMP_NE) return; + // If split condition predicate is GT or GE then first execute + // false branch of split condition. + if (CI->getPredicate() != ICmpInst::ICMP_ULT + && CI->getPredicate() != ICmpInst::ICMP_SLT + && CI->getPredicate() != ICmpInst::ICMP_ULE + && CI->getPredicate() != ICmpInst::ICMP_SLE) + SD.UseTrueBranchFirst = false; + // If one operand is loop invariant and second operand is SCEVAddRecExpr // based on induction variable then CI is a candidate split condition. Value *V0 = CI->getOperand(0); @@ -878,16 +894,30 @@ //[*] Eliminate split condition's inactive branch from ALoop. BasicBlock *A_SplitCondBlock = SD.SplitCondition->getParent(); BranchInst *A_BR = cast(A_SplitCondBlock->getTerminator()); - BasicBlock *A_InactiveBranch = A_BR->getSuccessor(1); - BasicBlock *A_ActiveBranch = A_BR->getSuccessor(0); + BasicBlock *A_InactiveBranch = NULL; + BasicBlock *A_ActiveBranch = NULL; + if (SD.UseTrueBranchFirst) { + A_ActiveBranch = A_BR->getSuccessor(0); + A_InactiveBranch = A_BR->getSuccessor(1); + } else { + A_ActiveBranch = A_BR->getSuccessor(1); + A_InactiveBranch = A_BR->getSuccessor(0); + } A_BR->setUnconditionalDest(A_BR->getSuccessor(0)); removeBlocks(A_InactiveBranch, L, A_ActiveBranch); //[*] Eliminate split condition's inactive branch in from BLoop. BasicBlock *B_SplitCondBlock = cast(ValueMap[A_SplitCondBlock]); BranchInst *B_BR = cast(B_SplitCondBlock->getTerminator()); - BasicBlock *B_InactiveBranch = B_BR->getSuccessor(0); - BasicBlock *B_ActiveBranch = B_BR->getSuccessor(1); + BasicBlock *B_InactiveBranch = NULL; + BasicBlock *B_ActiveBranch = NULL; + if (SD.UseTrueBranchFirst) { + B_ActiveBranch = B_BR->getSuccessor(1); + B_InactiveBranch = B_BR->getSuccessor(0); + } else { + B_ActiveBranch = B_BR->getSuccessor(0); + B_InactiveBranch = B_BR->getSuccessor(1); + } B_BR->setUnconditionalDest(B_BR->getSuccessor(1)); removeBlocks(B_InactiveBranch, BLoop, B_ActiveBranch); From espindola at google.com Fri Aug 24 06:44:24 2007 From: espindola at google.com (Rafael Espindola) Date: Fri, 24 Aug 2007 12:44:24 +0100 Subject: [llvm-commits] [patch] call libc memcpy/memset for big arrays Message-ID: <38a0d8450708240444y11d4b93esde577f1c60717f4d@mail.gmail.com> Currently we expand a memcpy/memset node to a call to the libc implementation if if ((Align & 3) != 0 || (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) { Shouldn't this be a ">". The libc memcpy/memset are very fast for big arrays. If I compile --------------------------------------- #include void f1(long *a, long *b) { memcpy(a, b, 8 * 16); } void f2(long *a, long *b) { memcpy(a, b, 8 * 32); } --------------------------------------- with gcc 4.2 (-O2), it will call memcpy for f2 and not for f1. Cheers, -- Rafael Avila de Espindola Google Ireland Ltd. Gordon House Barrow Street Dublin 4 Ireland Registered in Dublin, Ireland Registration Number: 368047 -------------- next part -------------- A non-text attachment was scrubbed... Name: memcpy.patch Type: text/x-patch Size: 1493 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070824/da7d9d51/attachment.bin From espindola at google.com Fri Aug 24 08:31:56 2007 From: espindola at google.com (Rafael Espindola) Date: Fri, 24 Aug 2007 14:31:56 +0100 Subject: [llvm-commits] [patch] fix the alignment of i64 and f64 on linux x86-64 Message-ID: <38a0d8450708240631q32f04c38i5c1c16e9d1e337f0@mail.gmail.com> According to table 3.1 of http://www.x86-64.org/documentation/abi.pdf, the i64 and f64 types should have 8 byte alignment. The attached patch changes this for targets that are not darwin. OK to commit? Cheers, -- Rafael Avila de Espindola Google Ireland Ltd. Gordon House Barrow Street Dublin 4 Ireland Registered in Dublin, Ireland Registration Number: 368047 -------------- next part -------------- A non-text attachment was scrubbed... Name: align.patch Type: text/x-patch Size: 911 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20070824/6f5c6599/attachment.bin From sabre at nondot.org Fri Aug 24 10:18:00 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 24 Aug 2007 15:18:00 -0000 Subject: [llvm-commits] [llvm] r41359 - /llvm/trunk/lib/Target/X86/README-SSE.txt Message-ID: <200708241518.l7OFI0ct028255@zion.cs.uiuc.edu> Author: lattner Date: Fri Aug 24 10:17:59 2007 New Revision: 41359 URL: http://llvm.org/viewvc/llvm-project?rev=41359&view=rev Log: add a note Modified: llvm/trunk/lib/Target/X86/README-SSE.txt Modified: llvm/trunk/lib/Target/X86/README-SSE.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README-SSE.txt?rev=41359&r1=41358&r2=41359&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README-SSE.txt (original) +++ llvm/trunk/lib/Target/X86/README-SSE.txt Fri Aug 24 10:17:59 2007 @@ -630,3 +630,17 @@ ret //===---------------------------------------------------------------------===// + +We should materialize vecetor constants like "all ones" and "signbit" with +code like: + + cmpeqps xmm1, xmm1 ; xmm1 = all-ones + +and: + cmpeqps xmm1, xmm1 ; xmm1 = all-ones + psrlq xmm1, 31 ; xmm1 = all 100000000000... + +instead of using a load from the constant pool. The later is important for +ABS/NEG/copysign etc. + +//===---------------------------------------------------------------------===// From sabre at nondot.org Fri Aug 24 11:00:15 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 24 Aug 2007 16:00:15 -0000 Subject: [llvm-commits] [llvm] r41360 - /llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Message-ID: <200708241600.l7OG0F96030085@zion.cs.uiuc.edu> Author: lattner Date: Fri Aug 24 11:00:15 2007 New Revision: 41360 URL: http://llvm.org/viewvc/llvm-project?rev=41360&view=rev Log: Disable EH generation until PPC works 100%. Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp?rev=41360&r1=41359&r2=41360&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Fri Aug 24 11:00:15 2007 @@ -59,7 +59,7 @@ UsedDirective = "\t.no_dead_strip\t"; WeakRefDirective = "\t.weak_reference\t"; HiddenDirective = "\t.private_extern\t"; - SupportsExceptionHandling = true; + SupportsExceptionHandling = false; DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; From dpatel at apple.com Fri Aug 24 14:32:26 2007 From: dpatel at apple.com (Devang Patel) Date: Fri, 24 Aug 2007 19:32:26 -0000 Subject: [llvm-commits] [llvm] r41365 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708241932.l7OJWQmF005053@zion.cs.uiuc.edu> Author: dpatel Date: Fri Aug 24 14:32:26 2007 New Revision: 41365 URL: http://llvm.org/viewvc/llvm-project?rev=41365&view=rev Log: Fix regression that I caused yesterday night while adding logic to select appropriate split condition branch. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41365&r1=41364&r2=41365&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 14:32:26 2007 @@ -903,7 +903,7 @@ A_ActiveBranch = A_BR->getSuccessor(1); A_InactiveBranch = A_BR->getSuccessor(0); } - A_BR->setUnconditionalDest(A_BR->getSuccessor(0)); + A_BR->setUnconditionalDest(A_ActiveBranch); removeBlocks(A_InactiveBranch, L, A_ActiveBranch); //[*] Eliminate split condition's inactive branch in from BLoop. @@ -918,7 +918,7 @@ B_ActiveBranch = B_BR->getSuccessor(0); B_InactiveBranch = B_BR->getSuccessor(1); } - B_BR->setUnconditionalDest(B_BR->getSuccessor(1)); + B_BR->setUnconditionalDest(B_ActiveBranch); removeBlocks(B_InactiveBranch, BLoop, B_ActiveBranch); return true; From baldrick at free.fr Fri Aug 24 15:12:43 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 24 Aug 2007 20:12:43 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r41367 - /llvm-gcc-4.2/trunk/gcc/ada/lang-specs.h Message-ID: <200708242012.l7OKChhU007213@zion.cs.uiuc.edu> Author: baldrick Date: Fri Aug 24 15:12:43 2007 New Revision: 41367 URL: http://llvm.org/viewvc/llvm-project?rev=41367&view=rev Log: Teach the Ada front-end about llvm options. Modified: llvm-gcc-4.2/trunk/gcc/ada/lang-specs.h Modified: llvm-gcc-4.2/trunk/gcc/ada/lang-specs.h URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/ada/lang-specs.h?rev=41367&r1=41366&r2=41367&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/ada/lang-specs.h (original) +++ llvm-gcc-4.2/trunk/gcc/ada/lang-specs.h Fri Aug 24 15:12:43 2007 @@ -37,6 +37,8 @@ %{nostdlib*}\ -dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}}\ %{O*} %{W*} %{w} %{p} %{pg:-p} %{a} %{f*} %{d*} %{g*&m*} %1\ + "/* LLVM LOCAL */"\ + %(llvm_options) \ %{!S:%{o*:%w%*-gnatO}} \ %i %{S:%W{o*}%{!o*:-o %b.s}} \ %{gnatc*|gnats*: -o %j} %{-param*} \ From sabre at nondot.org Fri Aug 24 15:48:18 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 24 Aug 2007 20:48:18 -0000 Subject: [llvm-commits] [llvm] r41371 - in /llvm/trunk: include/llvm/InstrTypes.h include/llvm/Instructions.h lib/VMCore/Instructions.cpp Message-ID: <200708242048.l7OKmItK008709@zion.cs.uiuc.edu> Author: lattner Date: Fri Aug 24 15:48:18 2007 New Revision: 41371 URL: http://llvm.org/viewvc/llvm-project?rev=41371&view=rev Log: sink clone() down the class hierarchy from CmpInst into ICmpInst/FCmpInst. This eliminates a conditional on that path, and ensures ICmpInst/FCmpInst both have an out-of-line virtual method to home the class. Modified: llvm/trunk/include/llvm/InstrTypes.h llvm/trunk/include/llvm/Instructions.h llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/include/llvm/InstrTypes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=41371&r1=41370&r2=41371&view=diff ============================================================================== --- llvm/trunk/include/llvm/InstrTypes.h (original) +++ llvm/trunk/include/llvm/InstrTypes.h Fri Aug 24 15:48:18 2007 @@ -494,9 +494,6 @@ Value *S2, const std::string &Name, BasicBlock *InsertAtEnd); - /// @brief Implement superclass method. - virtual CmpInst *clone() const; - /// @brief Get the opcode casted to the right type OtherOps getOpcode() const { return static_cast(Instruction::getOpcode()); Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=41371&r1=41370&r2=41371&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Fri Aug 24 15:48:18 2007 @@ -603,6 +603,8 @@ std::swap(Ops[0], Ops[1]); } + virtual ICmpInst *clone() const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const ICmpInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -725,6 +727,8 @@ std::swap(Ops[0], Ops[1]); } + virtual FCmpInst *clone() const; + /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FCmpInst *) { return true; } static inline bool classof(const Instruction *I) { Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=41371&r1=41370&r2=41371&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Fri Aug 24 15:48:18 2007 @@ -2595,8 +2595,11 @@ return create(getOpcode(), Ops[0], Ops[1]); } -CmpInst* CmpInst::clone() const { - return create(getOpcode(), getPredicate(), Ops[0], Ops[1]); +FCmpInst* FCmpInst::clone() const { + return new FCmpInst(getPredicate(), Ops[0], Ops[1]); +} +ICmpInst* ICmpInst::clone() const { + return new ICmpInst(getPredicate(), Ops[0], Ops[1]); } MallocInst *MallocInst::clone() const { return new MallocInst(*this); } From dalej at apple.com Fri Aug 24 15:59:17 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 24 Aug 2007 20:59:17 -0000 Subject: [llvm-commits] [llvm] r41372 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200708242059.l7OKxHjE009144@zion.cs.uiuc.edu> Author: johannes Date: Fri Aug 24 15:59:15 2007 New Revision: 41372 URL: http://llvm.org/viewvc/llvm-project?rev=41372&view=rev Log: Use APFloat internally for ConstantFPSDNode. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=41372&r1=41371&r2=41372&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Fri Aug 24 15:59:15 2007 @@ -23,6 +23,7 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/iterator" +#include "llvm/ADT/APFloat.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/DataTypes.h" #include @@ -1144,17 +1145,17 @@ }; class ConstantFPSDNode : public SDNode { - double Value; + APFloat Value; virtual void ANCHOR(); // Out-of-line virtual method to give class a home. protected: friend class SelectionDAG; ConstantFPSDNode(bool isTarget, double val, MVT::ValueType VT) : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, - getSDVTList(VT)), Value(val) { + getSDVTList(VT)), Value(APFloat(val)) { } public: - double getValue() const { return Value; } + double getValue() const { return Value.convertToDouble(); } /// isExactlyValue - We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=41372&r1=41371&r2=41372&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Aug 24 15:59:15 2007 @@ -49,7 +49,7 @@ /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. bool ConstantFPSDNode::isExactlyValue(double V) const { - return DoubleToBits(V) == DoubleToBits(Value); + return Value == APFloat(V); } //===----------------------------------------------------------------------===// From dalej at apple.com Fri Aug 24 17:09:56 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 24 Aug 2007 22:09:56 -0000 Subject: [llvm-commits] [llvm] r41378 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Support/APFloat.cpp lib/VMCore/Constants.cpp Message-ID: <200708242209.l7OM9uRp012069@zion.cs.uiuc.edu> Author: johannes Date: Fri Aug 24 17:09:56 2007 New Revision: 41378 URL: http://llvm.org/viewvc/llvm-project?rev=41378&view=rev Log: Poison APFloat::operator==. Replace existing uses with bitwiseIsEqual. This means backing out the preceding change to Constants.cpp, alas. Modified: llvm/trunk/include/llvm/ADT/APFloat.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp llvm/trunk/lib/Support/APFloat.cpp llvm/trunk/lib/VMCore/Constants.cpp Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=41378&r1=41377&r2=41378&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Fri Aug 24 17:09:56 2007 @@ -187,17 +187,17 @@ double convertToDouble() const; float convertToFloat() const; + /* The definition of equality is not straightforward for floating point, + so we won't use operator==. Use one of the following, or write + whatever it is you really mean. */ + bool operator==(const APFloat &) const; // DO NOT IMPLEMENT + /* IEEE comparison with another floating point number (QNaNs compare unordered, 0==-0). */ cmpResult compare(const APFloat &) const; /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */ - bool operator==(const APFloat &) const; - - /* Inversion of the preceding. */ - inline bool operator!=(const APFloat &RHS) const { - return !((*this)==RHS); - } + bool bitwiseIsEqual(const APFloat &) const; /* Simple queries. */ fltCategory getCategory() const { return category; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=41378&r1=41377&r2=41378&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Aug 24 17:09:56 2007 @@ -49,7 +49,7 @@ /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. bool ConstantFPSDNode::isExactlyValue(double V) const { - return Value == APFloat(V); + return Value.bitwiseIsEqual(APFloat(V)); } //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=41378&r1=41377&r2=41378&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Fri Aug 24 17:09:56 2007 @@ -276,7 +276,7 @@ } bool -APFloat::operator==(const APFloat &rhs) const { +APFloat::bitwiseIsEqual(const APFloat &rhs) const { if (this == &rhs) return true; if (semantics != rhs.semantics || Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=41378&r1=41377&r2=41378&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Fri Aug 24 17:09:56 2007 @@ -248,19 +248,30 @@ } bool ConstantFP::isExactlyValue(double V) const { - return Val == APFloat(V); + return Val.bitwiseIsEqual(APFloat(V)); } namespace { struct DenseMapAPFloatKeyInfo { - static inline APFloat getEmptyKey() { - return APFloat(APFloat::Bogus,1); + struct KeyTy { + APFloat val; + KeyTy(const APFloat& V) : val(V){} + KeyTy(const KeyTy& that) : val(that.val) {} + bool operator==(const KeyTy& that) const { + return this->val.bitwiseIsEqual(that.val); + } + bool operator!=(const KeyTy& that) const { + return !this->operator==(that); + } + }; + static inline KeyTy getEmptyKey() { + return KeyTy(APFloat(APFloat::Bogus,1)); } - static inline APFloat getTombstoneKey() { - return APFloat(APFloat::Bogus,2); + static inline KeyTy getTombstoneKey() { + return KeyTy(APFloat(APFloat::Bogus,2)); } - static unsigned getHashValue(const APFloat &Key) { - return Key.getHashValue(); + static unsigned getHashValue(const KeyTy &Key) { + return Key.val.getHashValue(); } static bool isPod() { return false; } }; @@ -268,21 +279,21 @@ //---- ConstantFP::get() implementation... // -typedef DenseMap FPMapTy; static ManagedStatic FPConstants; ConstantFP *ConstantFP::get(const Type *Ty, double V) { if (Ty == Type::FloatTy) { - APFloat Key(APFloat((float)V)); + DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((float)V)); ConstantFP *&Slot = (*FPConstants)[Key]; if (Slot) return Slot; return Slot = new ConstantFP(Ty, (float)V); } else if (Ty == Type::DoubleTy) { // Without the redundant cast, the following is taken to be // a function declaration. What a language. - APFloat Key(APFloat((double)V)); + DenseMapAPFloatKeyInfo::KeyTy Key(APFloat((double)V)); ConstantFP *&Slot = (*FPConstants)[Key]; if (Slot) return Slot; return Slot = new ConstantFP(Ty, V); From clattner at apple.com Fri Aug 24 18:03:07 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 24 Aug 2007 16:03:07 -0700 Subject: [llvm-commits] [llvm] r41378 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Support/APFloat.cpp lib/VMCore/Constants.cpp In-Reply-To: <200708242209.l7OM9uRp012069@zion.cs.uiuc.edu> References: <200708242209.l7OM9uRp012069@zion.cs.uiuc.edu> Message-ID: <04550391-A0BF-4281-8AF5-0069318ABFDA@apple.com> > > + /* The definition of equality is not straightforward for > floating point, > + so we won't use operator==. Use one of the following, or > write > + whatever it is you really mean. */ > + bool operator==(const APFloat &) const; // DO NOT IMPLEMENT Hey Dale, I think that you can just remove this and the compiler will give you a compile-time error if you try to use it. If you define it like this, you just get a link-time error. -Chris From tonic at nondot.org Fri Aug 24 18:23:23 2007 From: tonic at nondot.org (Tanya Lattner) Date: Fri, 24 Aug 2007 23:23:23 -0000 Subject: [llvm-commits] [llvm] r41380 - /llvm/trunk/docs/LinkTimeOptimization.html Message-ID: <200708242323.l7ONNNpT014724@zion.cs.uiuc.edu> Author: tbrethou Date: Fri Aug 24 18:23:23 2007 New Revision: 41380 URL: http://llvm.org/viewvc/llvm-project?rev=41380&view=rev Log: Rename llvm-gcc4 to llvm-gcc. Modified: llvm/trunk/docs/LinkTimeOptimization.html Modified: llvm/trunk/docs/LinkTimeOptimization.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LinkTimeOptimization.html?rev=41380&r1=41379&r2=41380&view=diff ============================================================================== --- llvm/trunk/docs/LinkTimeOptimization.html (original) +++ llvm/trunk/docs/LinkTimeOptimization.html Fri Aug 24 18:23:23 2007 @@ -85,7 +85,7 @@

The following example illustrates the advantages of LTO's integrated approach and clean interface. This example requires a system linker which supports LTO through the interface described in this document. Here, - llvm-gcc4 transparently invokes system linker.

+ llvm-gcc transparently invokes system linker.

  • Input source file a.c is compiled into LLVM bitcode form.
  • Input source file main.c is compiled into native object code. @@ -131,9 +131,9 @@ } --- command lines --- -$ llvm-gcc4 --emit-llvm -c a.c -o a.o # <-- a.o is LLVM bitcode file -$ llvm-gcc4 -c main.c -o main.o # <-- main.o is native object file -$ llvm-gcc4 a.o main.o -o main # <-- standard link command without any modifications +$ llvm-gcc --emit-llvm -c a.c -o a.o # <-- a.o is LLVM bitcode file +$ llvm-gcc -c main.c -o main.o # <-- main.o is native object file +$ llvm-gcc a.o main.o -o main # <-- standard link command without any modifications

    In this example, the linker recognizes that foo2() is an externally visible symbol defined in LLVM bitcode file. This information From tonic at nondot.org Fri Aug 24 18:31:09 2007 From: tonic at nondot.org (Tanya Lattner) Date: Fri, 24 Aug 2007 18:31:09 -0500 Subject: [llvm-commits] CVS: llvm-www/InTheNews.html Message-ID: <200708242331.l7ONV9iL015036@zion.cs.uiuc.edu> Changes in directory llvm-www: InTheNews.html updated: 1.21 -> 1.22 --- Log message: Fix broken link. --- Diffs of the changes: (+2 -2) InTheNews.html | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm-www/InTheNews.html diff -u llvm-www/InTheNews.html:1.21 llvm-www/InTheNews.html:1.22 --- llvm-www/InTheNews.html:1.21 Sat Jun 2 18:15:32 2007 +++ llvm-www/InTheNews.html Fri Aug 24 18:30:36 2007 @@ -36,7 +36,7 @@

  • 2007-01-22, Automotive Design Line, "Hardware generation method anticipates design reuse" (LLVM used in AH IR compiler flow), K.C. Krishnadas.
  • -
  • 2007-01-15, +
  • 2007-01-15, Linux.conf.au, "The ARM Backend Of LLVM", Rafael Espindola.
  • 2007-01-13, Leonard Ritter Blog, "Lunar goes LLVM", Leonard Ritter.
  • @@ -108,6 +108,6 @@ Valid HTML 4.01!
    - Last modified: $Date: 2007/06/02 23:15:32 $ + Last modified: $Date: 2007/08/24 23:30:36 $ From dalej at apple.com Fri Aug 24 18:38:45 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 24 Aug 2007 16:38:45 -0700 Subject: [llvm-commits] [llvm] r41378 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Support/APFloat.cpp lib/VMCore/Constants.cpp In-Reply-To: <04550391-A0BF-4281-8AF5-0069318ABFDA@apple.com> References: <200708242209.l7OM9uRp012069@zion.cs.uiuc.edu> <04550391-A0BF-4281-8AF5-0069318ABFDA@apple.com> Message-ID: On Aug 24, 2007, at 4:03 PM, Chris Lattner wrote: >> >> + /* The definition of equality is not straightforward for >> floating point, >> + so we won't use operator==. Use one of the following, or >> write >> + whatever it is you really mean. */ >> + bool operator==(const APFloat &) const; // DO NOT IMPLEMENT > > Hey Dale, > > I think that you can just remove this and the compiler will give you > a compile-time error if you try to use it. If you define it like > this, you just get a link-time error. Yep, and the linker error message doesn't tell you where the reference is coming from (I'm speaking from experience). I mostly did it this way because I see about 40 other places it was done this way, and I do see the utility as a statement of intent. Why is this one different? From clattner at apple.com Fri Aug 24 18:40:45 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 24 Aug 2007 16:40:45 -0700 Subject: [llvm-commits] [llvm] r41378 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Support/APFloat.cpp lib/VMCore/Constants.cpp In-Reply-To: References: <200708242209.l7OM9uRp012069@zion.cs.uiuc.edu> <04550391-A0BF-4281-8AF5-0069318ABFDA@apple.com> Message-ID: On Aug 24, 2007, at 4:38 PM, Dale Johannesen wrote: > > On Aug 24, 2007, at 4:03 PM, Chris Lattner wrote: > >>> >>> + /* The definition of equality is not straightforward for >>> floating point, >>> + so we won't use operator==. Use one of the following, or >>> write >>> + whatever it is you really mean. */ >>> + bool operator==(const APFloat &) const; // DO NOT IMPLEMENT >> >> Hey Dale, >> >> I think that you can just remove this and the compiler will give you >> a compile-time error if you try to use it. If you define it like >> this, you just get a link-time error. > > Yep, and the linker error message doesn't tell you where the > reference is coming from (I'm speaking from experience). I mostly > did it this way because I see about 40 other places it was done this > way, and I do see the utility as a statement of intent. Why is this > one different? The difference here is that C++ compilers automatically synthesis copy ctors and default ctors and operator=, but they don't do the same for operator==. To disable these automatically generated members, you have to "define" them, and put them in the private part of the class (so any users will get compile-time access violation errors as well as link errors). -Chris From dalej at apple.com Fri Aug 24 18:47:05 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 24 Aug 2007 16:47:05 -0700 Subject: [llvm-commits] [llvm] r41378 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Support/APFloat.cpp lib/VMCore/Constants.cpp In-Reply-To: References: <200708242209.l7OM9uRp012069@zion.cs.uiuc.edu> <04550391-A0BF-4281-8AF5-0069318ABFDA@apple.com> Message-ID: <5BF01958-F3F0-4270-A963-EC622269D3C3@apple.com> On Aug 24, 2007, at 4:40 PM, Chris Lattner wrote: >>> I think that you can just remove this and the compiler will give you >>> a compile-time error if you try to use it. If you define it like >>> this, you just get a link-time error. >> >> Yep, and the linker error message doesn't tell you where the >> reference is coming from (I'm speaking from experience). I mostly >> did it this way because I see about 40 other places it was done this >> way, and I do see the utility as a statement of intent. Why is this >> one different? > > The difference here is that C++ compilers automatically synthesis > copy ctors and default ctors and operator=, but they don't do the > same for operator==. To disable these automatically generated > members, you have to "define" them, and put them in the private part > of the class (so any users will get compile-time access violation > errors as well as link errors). Still learning that language. OK then, I'll comment it out. From clattner at apple.com Fri Aug 24 18:49:55 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 24 Aug 2007 16:49:55 -0700 Subject: [llvm-commits] [llvm] r41378 - in /llvm/trunk: include/llvm/ADT/APFloat.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Support/APFloat.cpp lib/VMCore/Constants.cpp In-Reply-To: <5BF01958-F3F0-4270-A963-EC622269D3C3@apple.com> References: <200708242209.l7OM9uRp012069@zion.cs.uiuc.edu> <04550391-A0BF-4281-8AF5-0069318ABFDA@apple.com> <5BF01958-F3F0-4270-A963-EC622269D3C3@apple.com> Message-ID: <97F84E90-7DFC-4DAC-880E-3AAEE59CD90D@apple.com> >> The difference here is that C++ compilers automatically synthesis >> copy ctors and default ctors and operator=, but they don't do the >> same for operator==. To disable these automatically generated >> members, you have to "define" them, and put them in the private part >> of the class (so any users will get compile-time access violation >> errors as well as link errors). > > Still learning that language. OK then, I'll comment it out. Not a big deal. Thanks Dale! -Chris From neil at daikokuya.co.uk Fri Aug 24 19:31:24 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Sat, 25 Aug 2007 00:31:24 -0000 Subject: [llvm-commits] [llvm] r41381 - /llvm/trunk/CREDITS.TXT Message-ID: <200708250031.l7P0VOv9007352@zion.cs.uiuc.edu> Author: neil Date: Fri Aug 24 19:31:24 2007 New Revision: 41381 URL: http://llvm.org/viewvc/llvm-project?rev=41381&view=rev Log: Add self Modified: llvm/trunk/CREDITS.TXT Modified: llvm/trunk/CREDITS.TXT URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CREDITS.TXT?rev=41381&r1=41380&r2=41381&view=diff ============================================================================== --- llvm/trunk/CREDITS.TXT (original) +++ llvm/trunk/CREDITS.TXT Fri Aug 24 19:31:24 2007 @@ -30,6 +30,10 @@ E: dberlin at dberlin.org D: ET-Forest implementation. +N: Neil Booth +E: neil at daikokuya.co.uk +D: APFloat implementation. + N: Misha Brukman E: brukman+llvm at uiuc.edu W: http://misha.brukman.net From neil at daikokuya.co.uk Fri Aug 24 19:36:22 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Sat, 25 Aug 2007 00:36:22 -0000 Subject: [llvm-commits] [llvm] r41382 - /llvm/trunk/CREDITS.TXT Message-ID: <200708250036.l7P0aM5m008128@zion.cs.uiuc.edu> Author: neil Date: Fri Aug 24 19:36:22 2007 New Revision: 41382 URL: http://llvm.org/viewvc/llvm-project?rev=41382&view=rev Log: Test Modified: llvm/trunk/CREDITS.TXT Modified: llvm/trunk/CREDITS.TXT URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/CREDITS.TXT?rev=41382&r1=41381&r2=41382&view=diff ============================================================================== --- llvm/trunk/CREDITS.TXT (original) +++ llvm/trunk/CREDITS.TXT Fri Aug 24 19:36:22 2007 @@ -32,7 +32,7 @@ N: Neil Booth E: neil at daikokuya.co.uk -D: APFloat implementation. +D: APFloat implementation. N: Misha Brukman E: brukman+llvm at uiuc.edu From dalej at apple.com Fri Aug 24 19:40:44 2007 From: dalej at apple.com (Dale Johannesen) Date: Sat, 25 Aug 2007 00:40:44 -0000 Subject: [llvm-commits] [llvm] r41383 - /llvm/trunk/include/llvm/ADT/APFloat.h Message-ID: <200708250040.l7P0eiHs008251@zion.cs.uiuc.edu> Author: johannes Date: Fri Aug 24 19:40:41 2007 New Revision: 41383 URL: http://llvm.org/viewvc/llvm-project?rev=41383&view=rev Log: Comment out declaration of operator== (undefined). Modified: llvm/trunk/include/llvm/ADT/APFloat.h Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=41383&r1=41382&r2=41383&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Fri Aug 24 19:40:41 2007 @@ -190,7 +190,7 @@ /* The definition of equality is not straightforward for floating point, so we won't use operator==. Use one of the following, or write whatever it is you really mean. */ - bool operator==(const APFloat &) const; // DO NOT IMPLEMENT + // bool operator==(const APFloat &) const; // DO NOT IMPLEMENT /* IEEE comparison with another floating point number (QNaNs compare unordered, 0==-0). */ From sabre at nondot.org Fri Aug 24 19:47:38 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 25 Aug 2007 00:47:38 -0000 Subject: [llvm-commits] [llvm] r41384 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h Message-ID: <200708250047.l7P0ldIt008428@zion.cs.uiuc.edu> Author: lattner Date: Fri Aug 24 19:47:38 2007 New Revision: 41384 URL: http://llvm.org/viewvc/llvm-project?rev=41384&view=rev Log: rename isOperandValidForConstraint to LowerAsmOperandForConstraint, changing the interface to allow for future changes. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=41384&r1=41383&r2=41384&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Fri Aug 24 19:47:38 2007 @@ -907,12 +907,11 @@ MVT::ValueType VT) const; - /// isOperandValidForConstraint - Return the specified operand (possibly - /// modified) if the specified SDOperand is valid for the specified target - /// constraint letter, otherwise return null. - virtual SDOperand - isOperandValidForConstraint(SDOperand Op, char ConstraintLetter, - SelectionDAG &DAG); + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops + /// vector. If it is invalid, don't add anything to Ops. + virtual void LowerAsmOperandForConstraint(SDOperand Op, char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG); //===--------------------------------------------------------------------===// // Scheduler hooks Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=41384&r1=41383&r2=41384&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Aug 24 19:47:38 2007 @@ -3623,20 +3623,20 @@ assert(!OpInfo.isIndirect && "Don't know how to handle indirect other inputs yet!"); - InOperandVal = TLI.isOperandValidForConstraint(InOperandVal, - OpInfo.ConstraintCode[0], - DAG); - if (!InOperandVal.Val) { + std::vector Ops; + TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode[0], + Ops, DAG); + if (Ops.empty()) { cerr << "Invalid operand for inline asm constraint '" << OpInfo.ConstraintCode << "'!\n"; exit(1); } // Add information to the INLINEASM node to know about this input. - unsigned ResOpType = 3 /*IMM*/ | (1 << 3); + unsigned ResOpType = 3 /*IMM*/ | (Ops.size() << 3); AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, TLI.getPointerTy())); - AsmNodeOperands.push_back(InOperandVal); + AsmNodeOperands.insert(AsmNodeOperands.end(), Ops.begin(), Ops.end()); break; } else if (OpInfo.ConstraintType == TargetLowering::C_Memory) { assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!"); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=41384&r1=41383&r2=41384&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Fri Aug 24 19:47:38 2007 @@ -1354,12 +1354,12 @@ return C_Unknown; } -/// isOperandValidForConstraint - Return the specified operand (possibly -/// modified) if the specified SDOperand is valid for the specified target -/// constraint letter, otherwise return null. -SDOperand TargetLowering::isOperandValidForConstraint(SDOperand Op, - char ConstraintLetter, - SelectionDAG &DAG) { +/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops +/// vector. If it is invalid, don't add anything to Ops. +void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op, + char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG) { switch (ConstraintLetter) { default: break; case 'i': // Simple Integer or Relocatable Constant @@ -1390,19 +1390,21 @@ if (ConstraintLetter != 'n') { int64_t Offs = GA->getOffset(); if (C) Offs += C->getValue(); - return DAG.getTargetGlobalAddress(GA->getGlobal(), Op.getValueType(), - Offs); + Ops.push_back(DAG.getTargetGlobalAddress(GA->getGlobal(), + Op.getValueType(), Offs)); + return; } } if (C) { // just C, no GV. // Simple constants are not allowed for 's'. - if (ConstraintLetter != 's') - return DAG.getTargetConstant(C->getValue(), Op.getValueType()); + if (ConstraintLetter != 's') { + Ops.push_back(DAG.getTargetConstant(C->getValue(), Op.getValueType())); + return; + } } break; } } - return SDOperand(0,0); } std::vector TargetLowering:: Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=41384&r1=41383&r2=41384&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Aug 24 19:47:38 2007 @@ -3338,9 +3338,12 @@ } -// isOperandValidForConstraint -SDOperand PPCTargetLowering:: -isOperandValidForConstraint(SDOperand Op, char Letter, SelectionDAG &DAG) { +/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops +/// vector. If it is invalid, don't add anything to Ops. +void PPCTargetLowering::LowerAsmOperandForConstraint(SDOperand Op, char Letter, + std::vector&Ops, + SelectionDAG &DAG) { + SDOperand Result(0,0); switch (Letter) { default: break; case 'I': @@ -3352,46 +3355,51 @@ case 'O': case 'P': { ConstantSDNode *CST = dyn_cast(Op); - if (!CST) return SDOperand(0, 0); // Must be an immediate to match. + if (!CST) return; // Must be an immediate to match. unsigned Value = CST->getValue(); switch (Letter) { default: assert(0 && "Unknown constraint letter!"); case 'I': // "I" is a signed 16-bit constant. if ((short)Value == (int)Value) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'J': // "J" is a constant with only the high-order 16 bits nonzero. case 'L': // "L" is a signed 16-bit constant shifted left 16 bits. if ((short)Value == 0) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'K': // "K" is a constant with only the low-order 16 bits nonzero. if ((Value >> 16) == 0) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'M': // "M" is a constant that is greater than 31. if (Value > 31) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'N': // "N" is a positive constant that is an exact power of two. if ((int)Value > 0 && isPowerOf2_32(Value)) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'O': // "O" is the constant zero. if (Value == 0) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; case 'P': // "P" is a constant whose negation is a signed 16-bit constant. if ((short)-Value == (int)-Value) - return DAG.getTargetConstant(Value, Op.getValueType()); + Result = DAG.getTargetConstant(Value, Op.getValueType()); break; } break; } } + if (Result.Val) { + Ops.push_back(Result); + return; + } + // Handle standard constraint letters. - return TargetLowering::isOperandValidForConstraint(Op, Letter, DAG); + TargetLowering::LowerAsmOperandForConstraint(Op, Letter, Ops, DAG); } // isLegalAddressingMode - Return true if the addressing mode represented Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=41384&r1=41383&r2=41384&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Fri Aug 24 19:47:38 2007 @@ -244,9 +244,14 @@ std::pair getRegForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const; - SDOperand isOperandValidForConstraint(SDOperand Op, char ConstraintLetter, - SelectionDAG &DAG); + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops + /// vector. If it is invalid, don't add anything to Ops. + virtual void LowerAsmOperandForConstraint(SDOperand Op, + char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG); + /// isLegalAddressingMode - Return true if the addressing mode represented /// by AM is legal for this target, for a load/store of the specified type. virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const; Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=41384&r1=41383&r2=41384&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Aug 24 19:47:38 2007 @@ -5002,29 +5002,38 @@ return TargetLowering::getConstraintType(Constraint); } -/// isOperandValidForConstraint - Return the specified operand (possibly -/// modified) if the specified SDOperand is valid for the specified target -/// constraint letter, otherwise return null. -SDOperand X86TargetLowering:: -isOperandValidForConstraint(SDOperand Op, char Constraint, SelectionDAG &DAG) { +/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops +/// vector. If it is invalid, don't add anything to Ops. +void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op, + char Constraint, + std::vector&Ops, + SelectionDAG &DAG) { + SDOperand Result(0, 0); + switch (Constraint) { default: break; case 'I': if (ConstantSDNode *C = dyn_cast(Op)) { - if (C->getValue() <= 31) - return DAG.getTargetConstant(C->getValue(), Op.getValueType()); + if (C->getValue() <= 31) { + Result = DAG.getTargetConstant(C->getValue(), Op.getValueType()); + break; + } } - return SDOperand(0,0); + return; case 'N': if (ConstantSDNode *C = dyn_cast(Op)) { - if (C->getValue() <= 255) - return DAG.getTargetConstant(C->getValue(), Op.getValueType()); + if (C->getValue() <= 255) { + Result = DAG.getTargetConstant(C->getValue(), Op.getValueType()); + break; + } } - return SDOperand(0,0); + return; case 'i': { // Literal immediates are always ok. - if (ConstantSDNode *CST = dyn_cast(Op)) - return DAG.getTargetConstant(CST->getValue(), Op.getValueType()); + if (ConstantSDNode *CST = dyn_cast(Op)) { + Result = DAG.getTargetConstant(CST->getValue(), Op.getValueType()); + break; + } // If we are in non-pic codegen mode, we allow the address of a global (with // an optional displacement) to be used with 'i'. @@ -5054,18 +5063,24 @@ // match. if (Subtarget->GVRequiresExtraLoad(GA->getGlobal(), getTargetMachine(), false)) - return SDOperand(0, 0); + return; Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), Offset); - return Op; + Result = Op; + break; } // Otherwise, not valid for this mode. - return SDOperand(0, 0); + return; } } - return TargetLowering::isOperandValidForConstraint(Op, Constraint, DAG); + + if (Result.Val) { + Ops.push_back(Result); + return; + } + return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); } std::vector X86TargetLowering:: Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=41384&r1=41383&r2=41384&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Fri Aug 24 19:47:38 2007 @@ -330,11 +330,13 @@ std::vector getRegClassForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const; - /// isOperandValidForConstraint - Return the specified operand (possibly - /// modified) if the specified SDOperand is valid for the specified target - /// constraint letter, otherwise return null. - SDOperand isOperandValidForConstraint(SDOperand Op, char ConstraintLetter, - SelectionDAG &DAG); + + /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops + /// vector. If it is invalid, don't add anything to Ops. + virtual void LowerAsmOperandForConstraint(SDOperand Op, + char ConstraintLetter, + std::vector &Ops, + SelectionDAG &DAG); /// getRegForInlineAsmConstraint - Given a physical register constraint /// (e.g. {edx}), return the register number and the register class for the From isanbard at gmail.com Fri Aug 24 19:51:55 2007 From: isanbard at gmail.com (Bill Wendling) Date: Sat, 25 Aug 2007 00:51:55 -0000 Subject: [llvm-commits] [llvm] r41385 - /llvm/trunk/lib/CodeGen/DwarfWriter.cpp Message-ID: <200708250051.l7P0ptLh008711@zion.cs.uiuc.edu> Author: void Date: Fri Aug 24 19:51:55 2007 New Revision: 41385 URL: http://llvm.org/viewvc/llvm-project?rev=41385&view=rev Log: The personality function might need to be declared as: .set Lset0,___gxx_personality_v0-. .long Lset0 on some targets. Make it so! Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfWriter.cpp?rev=41385&r1=41384&r2=41385&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DwarfWriter.cpp (original) +++ llvm/trunk/lib/CodeGen/DwarfWriter.cpp Fri Aug 24 19:51:55 2007 @@ -2803,11 +2803,24 @@ Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4); Asm->EOL("Personality (pcrel sdata4)"); - O << TAI->getData32bitsDirective(); - Asm->EmitExternalGlobal((const GlobalVariable *)(Personality)); - O << "-" << TAI->getPCSymbol(); - Asm->EOL("Personality"); - + if (TAI->needsSet()) { + O << "\t.set\t"; + PrintLabelName("set", SetCounter); + O << ","; + Asm->EmitExternalGlobal((const GlobalVariable *)(Personality)); + O << "-" << TAI->getPCSymbol(); + Asm->EOL("Set Personality"); + O << TAI->getData32bitsDirective(); + PrintLabelName("set", SetCounter); + Asm->EOL("Personality"); + ++SetCounter; + } else { + O << TAI->getData32bitsDirective(); + Asm->EmitExternalGlobal((const GlobalVariable *)(Personality)); + O << "-" << TAI->getPCSymbol(); + Asm->EOL("Personality"); + } + Asm->EmitULEB128Bytes(DW_EH_PE_pcrel); Asm->EOL("LSDA Encoding (pcrel)"); Asm->EmitULEB128Bytes(DW_EH_PE_pcrel); From sabre at nondot.org Fri Aug 24 19:53:07 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 25 Aug 2007 00:53:07 -0000 Subject: [llvm-commits] [llvm] r41386 - /llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200708250053.l7P0r7Fv008788@zion.cs.uiuc.edu> Author: lattner Date: Fri Aug 24 19:53:07 2007 New Revision: 41386 URL: http://llvm.org/viewvc/llvm-project?rev=41386&view=rev Log: Teach the dag scheduler to handle inline asm nodes with multi-value immediate operands. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=41386&r1=41385&r2=41386&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Aug 24 19:53:07 2007 @@ -753,15 +753,16 @@ } break; case 3: { // Immediate. - assert(NumVals == 1 && "Unknown immediate value!"); - if (ConstantSDNode *CS=dyn_cast(Node->getOperand(i))){ - MI->addImmOperand(CS->getValue()); - } else { - GlobalAddressSDNode *GA = - cast(Node->getOperand(i)); - MI->addGlobalAddressOperand(GA->getGlobal(), GA->getOffset()); + for (; NumVals; --NumVals, ++i) { + if (ConstantSDNode *CS = + dyn_cast(Node->getOperand(i))) { + MI->addImmOperand(CS->getValue()); + } else { + GlobalAddressSDNode *GA = + cast(Node->getOperand(i)); + MI->addGlobalAddressOperand(GA->getGlobal(), GA->getOffset()); + } } - ++i; break; } case 4: // Addressing mode. From dpatel at apple.com Fri Aug 24 19:56:38 2007 From: dpatel at apple.com (Devang Patel) Date: Sat, 25 Aug 2007 00:56:38 -0000 Subject: [llvm-commits] [llvm] r41387 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll Message-ID: <200708250056.l7P0udbv008892@zion.cs.uiuc.edu> Author: dpatel Date: Fri Aug 24 19:56:38 2007 New Revision: 41387 URL: http://llvm.org/viewvc/llvm-project?rev=41387&view=rev Log: While calculating upper loop bound for first loop and lower loop bound for second loop, take care of edge cases. Added: llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41387&r1=41386&r2=41387&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 19:56:38 2007 @@ -58,7 +58,8 @@ class SplitInfo { public: SplitInfo() : SplitValue(NULL), SplitCondition(NULL), - UseTrueBranchFirst(true) {} + UseTrueBranchFirst(true), A_ExitValue(NULL), + B_StartValue(NULL) {} // Induction variable's range is split at this value. Value *SplitValue; @@ -69,11 +70,20 @@ // True if after loop index split, first loop will execute split condition's // true branch. bool UseTrueBranchFirst; + + // Exit value for first loop after loop split. + Value *A_ExitValue; + + // Start value for second loop after loop split. + Value *B_StartValue; + // Clear split info. void clear() { SplitValue = NULL; SplitCondition = NULL; UseTrueBranchFirst = true; + A_ExitValue = NULL; + B_StartValue = NULL; } }; @@ -112,6 +122,10 @@ /// split loop using given split condition. bool safeSplitCondition(SplitInfo &SD); + /// calculateLoopBounds - ALoop exit value and BLoop start values are calculated + /// based on split value. + void calculateLoopBounds(SplitInfo &SD); + /// splitLoop - Split current loop L in two loops using split information /// SD. Update dominator information. Maintain LCSSA form. bool splitLoop(SplitInfo &SD); @@ -295,7 +309,14 @@ ICmpInst *CI = dyn_cast(BR->getCondition()); if (!CI) return; - + + // FIXME + if (CI->getPredicate() == ICmpInst::ICMP_SGT + || CI->getPredicate() == ICmpInst::ICMP_UGT + || CI->getPredicate() == ICmpInst::ICMP_SGE + || CI->getPredicate() == ICmpInst::ICMP_UGE) + return; + ExitCondition = CI; // Exit condition's one operand is loop invariant exit value and second @@ -747,6 +768,207 @@ return false; } +/// calculateLoopBounds - ALoop exit value and BLoop start values are calculated +/// based on split value. +void LoopIndexSplit::calculateLoopBounds(SplitInfo &SD) { + + ICmpInst::Predicate SP = SD.SplitCondition->getPredicate(); + const Type *Ty = SD.SplitValue->getType(); + bool Sign = ExitCondition->isSignedPredicate(); + BasicBlock *Preheader = L->getLoopPreheader(); + Instruction *PHTerminator = Preheader->getTerminator(); + + // Initially use split value as upper loop bound for first loop and lower loop + // bound for second loop. + Value *AEV = SD.SplitValue; + Value *BSV = SD.SplitValue; + + switch (ExitCondition->getPredicate()) { + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_UGT: + case ICmpInst::ICMP_SGE: + case ICmpInst::ICMP_UGE: + default: + assert (0 && "Unexpected exit condition predicate"); + + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_ULT: + { + switch (SP) { + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_ULT: + // + // for (i = LB; i < UB; ++i) { if (i < SV) A; else B; } + // + // is transformed into + // AEV = BSV = SV + // for (i = LB; i < min(UB, AEV); ++i) + // A; + // for (i = max(LB, BSV); i < UB; ++i); + // B; + break; + case ICmpInst::ICMP_SLE: + case ICmpInst::ICMP_ULE: + { + // + // for (i = LB; i < UB; ++i) { if (i <= SV) A; else B; } + // + // is transformed into + // + // AEV = SV + 1 + // BSV = SV + 1 + // for (i = LB; i < min(UB, AEV); ++i) + // A; + // for (i = max(LB, BSV); i < UB; ++i) + // B; + BSV = BinaryOperator::createAdd(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + AEV = BSV; + } + break; + case ICmpInst::ICMP_SGE: + case ICmpInst::ICMP_UGE: + // + // for (i = LB; i < UB; ++i) { if (i >= SV) A; else B; } + // + // is transformed into + // AEV = BSV = SV + // for (i = LB; i < min(UB, AEV); ++i) + // B; + // for (i = max(BSV, LB); i < UB; ++i) + // A; + break; + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_UGT: + { + // + // for (i = LB; i < UB; ++i) { if (i > SV) A; else B; } + // + // is transformed into + // + // BSV = AEV = SV + 1 + // for (i = LB; i < min(UB, AEV); ++i) + // B; + // for (i = max(LB, BSV); i < UB; ++i) + // A; + BSV = BinaryOperator::createAdd(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + AEV = BSV; + } + break; + default: + assert (0 && "Unexpected split condition predicate"); + break; + } // end switch (SP) + } + break; + case ICmpInst::ICMP_SLE: + case ICmpInst::ICMP_ULE: + { + switch (SP) { + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_ULT: + // + // for (i = LB; i <= UB; ++i) { if (i < SV) A; else B; } + // + // is transformed into + // AEV = SV - 1; + // BSV = SV; + // for (i = LB; i <= min(UB, AEV); ++i) + // A; + // for (i = max(LB, BSV); i <= UB; ++i) + // B; + AEV = BinaryOperator::createSub(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.sub", PHTerminator); + break; + case ICmpInst::ICMP_SLE: + case ICmpInst::ICMP_ULE: + // + // for (i = LB; i <= UB; ++i) { if (i <= SV) A; else B; } + // + // is transformed into + // AEV = SV; + // BSV = SV + 1; + // for (i = LB; i <= min(UB, AEV); ++i) + // A; + // for (i = max(LB, BSV); i <= UB; ++i) + // B; + BSV = BinaryOperator::createAdd(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + break; + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_UGT: + // + // for (i = LB; i <= UB; ++i) { if (i > SV) A; else B; } + // + // is transformed into + // AEV = SV; + // BSV = SV + 1; + // for (i = LB; i <= min(AEV, UB); ++i) + // B; + // for (i = max(LB, BSV); i <= UB; ++i) + // A; + BSV = BinaryOperator::createAdd(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.add", PHTerminator); + break; + case ICmpInst::ICMP_SGE: + case ICmpInst::ICMP_UGE: + // ** TODO ** + // + // for (i = LB; i <= UB; ++i) { if (i >= SV) A; else B; } + // + // is transformed into + // AEV = SV - 1; + // BSV = SV; + // for (i = LB; i <= min(AEV, UB); ++i) + // B; + // for (i = max(LB, BSV); i <= UB; ++i) + // A; + AEV = BinaryOperator::createSub(SD.SplitValue, + ConstantInt::get(Ty, 1, Sign), + "lsplit.sub", PHTerminator); + break; + default: + assert (0 && "Unexpected split condition predicate"); + break; + } // end switch (SP) + } + break; + } + + // Calculate ALoop induction variable's new exiting value and + // BLoop induction variable's new starting value. Calculuate these + // values in original loop's preheader. + // A_ExitValue = min(SplitValue, OrignalLoopExitValue) + // B_StartValue = max(SplitValue, OriginalLoopStartValue) + if (isa(SD.SplitValue)) { + SD.A_ExitValue = AEV; + SD.B_StartValue = BSV; + return; + } + + Value *C1 = new ICmpInst(Sign ? + ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + AEV, + ExitCondition->getOperand(ExitValueNum), + "lsplit.ev", PHTerminator); + SD.A_ExitValue = new SelectInst(C1, AEV, + ExitCondition->getOperand(ExitValueNum), + "lsplit.ev", PHTerminator); + + Value *C2 = new ICmpInst(Sign ? + ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, + BSV, StartValue, "lsplit.sv", + PHTerminator); + SD.B_StartValue = new SelectInst(C2, StartValue, BSV, + "lsplit.sv", PHTerminator); +} + /// splitLoop - Split current loop L in two loops using split information /// SD. Update dominator information. Maintain LCSSA form. bool LoopIndexSplit::splitLoop(SplitInfo &SD) { @@ -762,38 +984,11 @@ // // ALoop's exit edge enters BLoop's header through a forwarding block which // acts as a BLoop's preheader. + BasicBlock *Preheader = L->getLoopPreheader(); - //[*] Calculate ALoop induction variable's new exiting value and - // BLoop induction variable's new starting value. Calculuate these - // values in original loop's preheader. - // A_ExitValue = min(SplitValue, OrignalLoopExitValue) - // B_StartValue = max(SplitValue, OriginalLoopStartValue) - Value *A_ExitValue = NULL; - Value *B_StartValue = NULL; - if (isa(SD.SplitValue)) { - A_ExitValue = SD.SplitValue; - B_StartValue = SD.SplitValue; - } - else { - BasicBlock *Preheader = L->getLoopPreheader(); - Instruction *PHTerminator = Preheader->getTerminator(); - bool SignedPredicate = ExitCondition->isSignedPredicate(); - Value *C1 = new ICmpInst(SignedPredicate ? - ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - SD.SplitValue, - ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", PHTerminator); - A_ExitValue = new SelectInst(C1, SD.SplitValue, - ExitCondition->getOperand(ExitValueNum), - "lsplit.ev", PHTerminator); - - Value *C2 = new ICmpInst(SignedPredicate ? - ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - SD.SplitValue, StartValue, "lsplit.sv", - PHTerminator); - B_StartValue = new SelectInst(C2, StartValue, SD.SplitValue, - "lsplit.sv", PHTerminator); - } + // Calculate ALoop induction variable's new exiting value and + // BLoop induction variable's new starting value. + calculateLoopBounds(SD); //[*] Clone loop. DenseMap ValueMap; @@ -815,7 +1010,7 @@ A_ExitInsn->setSuccessor(1, B_Header); //[*] Update ALoop's exit value using new exit value. - ExitCondition->setOperand(ExitValueNum, A_ExitValue); + ExitCondition->setOperand(ExitValueNum, SD.A_ExitValue); // [*] Update BLoop's header phi nodes. Remove incoming PHINode's from // original loop's preheader. Add incoming PHINode values from @@ -831,7 +1026,7 @@ } else break; } - BasicBlock *Preheader = L->getLoopPreheader(); + for (BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast(BI)) { @@ -840,7 +1035,7 @@ // Add incoming value from A_ExitingBlock. if (PN == B_IndVar) - PN->addIncoming(B_StartValue, A_ExitingBlock); + PN->addIncoming(SD.B_StartValue, A_ExitingBlock); else { PHINode *OrigPN = cast(InverseMap[PN]); Value *V2 = OrigPN->getIncomingValueForBlock(A_ExitingBlock); Added: llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll?rev=41387&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll (added) +++ llvm/trunk/test/Transforms/LoopIndexSplit/SplitValue-2007-08-24.ll Fri Aug 24 19:56:38 2007 @@ -0,0 +1,52 @@ +; Split loop. Save last value. Split value is off by one in this example. +; RUN: llvm-as < %s | opt -loop-index-split -disable-output -stats |& \ +; RUN: grep "loop-index-split" | count 1 + + at k = external global i32 ; [#uses=2] + +define void @foobar(i32 %a, i32 %b) { +entry: + br label %bb + +bb: ; preds = %cond_next16, %entry + %i.01.0 = phi i32 [ 0, %entry ], [ %tmp18, %cond_next16 ] ; [#uses=5] + %tsum.18.0 = phi i32 [ 42, %entry ], [ %tsum.013.1, %cond_next16 ] ; [#uses=3] + %tmp1 = icmp sgt i32 %i.01.0, 50 ; [#uses=1] + br i1 %tmp1, label %cond_true, label %cond_false + +cond_true: ; preds = %bb + %tmp4 = tail call i32 @foo( i32 %i.01.0 ) ; [#uses=1] + %tmp6 = add i32 %tmp4, %tsum.18.0 ; [#uses=2] + %tmp914 = load i32* @k, align 4 ; [#uses=1] + %tmp1015 = icmp eq i32 %tmp914, 0 ; [#uses=1] + br i1 %tmp1015, label %cond_next16, label %cond_true13 + +cond_false: ; preds = %bb + %tmp8 = tail call i32 @bar( i32 %i.01.0 ) ; [#uses=0] + %tmp9 = load i32* @k, align 4 ; [#uses=1] + %tmp10 = icmp eq i32 %tmp9, 0 ; [#uses=1] + br i1 %tmp10, label %cond_next16, label %cond_true13 + +cond_true13: ; preds = %cond_false, %cond_true + %tsum.013.0 = phi i32 [ %tmp6, %cond_true ], [ %tsum.18.0, %cond_false ] ; [#uses=1] + %tmp15 = tail call i32 @bar( i32 %i.01.0 ) ; [#uses=0] + br label %cond_next16 + +cond_next16: ; preds = %cond_false, %cond_true, %cond_true13 + %tsum.013.1 = phi i32 [ %tsum.013.0, %cond_true13 ], [ %tmp6, %cond_true ], [ %tsum.18.0, %cond_false ] ; [#uses=2] + %tmp18 = add i32 %i.01.0, 1 ; [#uses=3] + %tmp21 = icmp slt i32 %tmp18, 100 ; [#uses=1] + br i1 %tmp21, label %bb, label %bb24 + +bb24: ; preds = %cond_next16 + %tmp18.lcssa = phi i32 [ %tmp18, %cond_next16 ] ; [#uses=1] + %tsum.013.1.lcssa = phi i32 [ %tsum.013.1, %cond_next16 ] ; [#uses=1] + %tmp27 = tail call i32 @t( i32 %tmp18.lcssa, i32 %tsum.013.1.lcssa ) ; [#uses=0] + ret void +} + +declare i32 @foo(i32) + +declare i32 @bar(i32) + +declare i32 @t(i32, i32) From sabre at nondot.org Fri Aug 24 20:00:22 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 25 Aug 2007 01:00:22 -0000 Subject: [llvm-commits] [llvm] r41388 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp test/CodeGen/Generic/asm-large-immediate.ll Message-ID: <200708250100.l7P10MQ6009045@zion.cs.uiuc.edu> Author: lattner Date: Fri Aug 24 20:00:22 2007 New Revision: 41388 URL: http://llvm.org/viewvc/llvm-project?rev=41388&view=rev Log: Allow target constants to be illegal types. The target should know how to handle them. This fixes test/CodeGen/Generic/asm-large-immediate.ll Added: llvm/trunk/test/CodeGen/Generic/asm-large-immediate.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=41388&r1=41387&r2=41388&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Aug 24 20:00:22 2007 @@ -457,6 +457,8 @@ // If this is an illegal scalar, expand it into its two component // pieces. SDOperand X, Y; + if (Op.getOpcode() == ISD::TargetConstant) + break; // Allow illegal target nodes. ExpandOp(Op, X, Y); } else if (MVT::getVectorNumElements(VT) == 1) { // If this is an illegal single element vector, convert it to a @@ -644,6 +646,9 @@ /// is legal, recursively ensuring that the operands' operations remain /// legal. SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { + if (Op.getOpcode() == ISD::TargetConstant) // Allow illegal target nodes. + return Op; + assert(isTypeLegal(Op.getValueType()) && "Caller should expand or promote operands that are not legal!"); SDNode *Node = Op.Val; Added: llvm/trunk/test/CodeGen/Generic/asm-large-immediate.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/asm-large-immediate.ll?rev=41388&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/Generic/asm-large-immediate.ll (added) +++ llvm/trunk/test/CodeGen/Generic/asm-large-immediate.ll Fri Aug 24 20:00:22 2007 @@ -0,0 +1,8 @@ +; RUN: llvm-as < %s | llc | grep 68719476738 + +define void @test() { +entry: + tail call void asm sideeffect "/* result: ${0:c} */", "i,~{dirflag},~{fpsr},~{flags}"( i64 68719476738 ) + ret void +} + From dpatel at apple.com Fri Aug 24 20:09:15 2007 From: dpatel at apple.com (Devang Patel) Date: Sat, 25 Aug 2007 01:09:15 -0000 Subject: [llvm-commits] [llvm] r41389 - in /llvm/trunk: lib/Transforms/Scalar/LoopIndexSplit.cpp test/Transforms/LoopIndexSplit/UpperBound-2007-08-24.ll Message-ID: <200708250109.l7P19FcW009371@zion.cs.uiuc.edu> Author: dpatel Date: Fri Aug 24 20:09:14 2007 New Revision: 41389 URL: http://llvm.org/viewvc/llvm-project?rev=41389&view=rev Log: Constant split values needs upper bound and lower bound check, just like any other split value. Added: llvm/trunk/test/Transforms/LoopIndexSplit/UpperBound-2007-08-24.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41389&r1=41388&r2=41389&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 20:09:14 2007 @@ -946,12 +946,6 @@ // values in original loop's preheader. // A_ExitValue = min(SplitValue, OrignalLoopExitValue) // B_StartValue = max(SplitValue, OriginalLoopStartValue) - if (isa(SD.SplitValue)) { - SD.A_ExitValue = AEV; - SD.B_StartValue = BSV; - return; - } - Value *C1 = new ICmpInst(Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, AEV, Added: llvm/trunk/test/Transforms/LoopIndexSplit/UpperBound-2007-08-24.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIndexSplit/UpperBound-2007-08-24.ll?rev=41389&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopIndexSplit/UpperBound-2007-08-24.ll (added) +++ llvm/trunk/test/Transforms/LoopIndexSplit/UpperBound-2007-08-24.ll Fri Aug 24 20:09:14 2007 @@ -0,0 +1,52 @@ +; Split loop. Split value is a constant and greater then exit value. +; Check whether optimizer inserts proper checkfor split value or not. +; RUN: llvm-as < %s | opt -loop-index-split | llvm-dis | grep select + + at k = external global i32 ; [#uses=2] + +define void @foobar(i32 %a, i32 %b) { +entry: + br label %bb + +bb: ; preds = %cond_next16, %entry + %i.01.0 = phi i32 [ 0, %entry ], [ %tmp18, %cond_next16 ] ; [#uses=5] + %tsum.18.0 = phi i32 [ 42, %entry ], [ %tsum.013.1, %cond_next16 ] ; [#uses=3] + %tmp1 = icmp slt i32 %i.01.0, 500 ; [#uses=1] + br i1 %tmp1, label %cond_true, label %cond_false + +cond_true: ; preds = %bb + %tmp4 = tail call i32 @foo( i32 %i.01.0 ) ; [#uses=1] + %tmp6 = add i32 %tmp4, %tsum.18.0 ; [#uses=2] + %tmp914 = load i32* @k, align 4 ; [#uses=1] + %tmp1015 = icmp eq i32 %tmp914, 0 ; [#uses=1] + br i1 %tmp1015, label %cond_next16, label %cond_true13 + +cond_false: ; preds = %bb + %tmp8 = tail call i32 @bar( i32 %i.01.0 ) ; [#uses=0] + %tmp9 = load i32* @k, align 4 ; [#uses=1] + %tmp10 = icmp eq i32 %tmp9, 0 ; [#uses=1] + br i1 %tmp10, label %cond_next16, label %cond_true13 + +cond_true13: ; preds = %cond_false, %cond_true + %tsum.013.0 = phi i32 [ %tmp6, %cond_true ], [ %tsum.18.0, %cond_false ] ; [#uses=1] + %tmp15 = tail call i32 @bar( i32 %i.01.0 ) ; [#uses=0] + br label %cond_next16 + +cond_next16: ; preds = %cond_false, %cond_true, %cond_true13 + %tsum.013.1 = phi i32 [ %tsum.013.0, %cond_true13 ], [ %tmp6, %cond_true ], [ %tsum.18.0, %cond_false ] ; [#uses=2] + %tmp18 = add i32 %i.01.0, 1 ; [#uses=3] + %tmp21 = icmp slt i32 %tmp18, 100 ; [#uses=1] + br i1 %tmp21, label %bb, label %bb24 + +bb24: ; preds = %cond_next16 + %tmp18.lcssa = phi i32 [ %tmp18, %cond_next16 ] ; [#uses=1] + %tsum.013.1.lcssa = phi i32 [ %tsum.013.1, %cond_next16 ] ; [#uses=1] + %tmp27 = tail call i32 @t( i32 %tmp18.lcssa, i32 %tsum.013.1.lcssa ) ; [#uses=0] + ret void +} + +declare i32 @foo(i32) + +declare i32 @bar(i32) + +declare i32 @t(i32, i32) From clattner at apple.com Fri Aug 24 20:15:55 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 24 Aug 2007 18:15:55 -0700 Subject: [llvm-commits] [patch] call libc memcpy/memset for big arrays In-Reply-To: <38a0d8450708240444y11d4b93esde577f1c60717f4d@mail.gmail.com> References: <38a0d8450708240444y11d4b93esde577f1c60717f4d@mail.gmail.com> Message-ID: On Aug 24, 2007, at 4:44 AM, Rafael Espindola wrote: > Currently we expand a memcpy/memset node to a call to the libc > implementation if > > if ((Align & 3) != 0 || > (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold())) { > > Shouldn't this be a ">". The libc memcpy/memset are very fast for > big arrays. Yep, that makes sense to me! Please commit. Dale, please review the commit when you get a chance, -Chris > If I compile > > --------------------------------------- > #include > void f1(long *a, long *b) { > memcpy(a, b, 8 * 16); > } > > void f2(long *a, long *b) { > memcpy(a, b, 8 * 32); > } > --------------------------------------- > > with gcc 4.2 (-O2), it will call memcpy for f2 and not for f1. > > Cheers, > -- > Rafael Avila de Espindola > > Google Ireland Ltd. > Gordon House > Barrow Street > Dublin 4 > Ireland > > Registered in Dublin, Ireland > Registration Number: 368047 > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dpatel at apple.com Fri Aug 24 21:39:24 2007 From: dpatel at apple.com (Devang Patel) Date: Sat, 25 Aug 2007 02:39:24 -0000 Subject: [llvm-commits] [llvm] r41394 - /llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Message-ID: <200708250239.l7P2dOZn011844@zion.cs.uiuc.edu> Author: dpatel Date: Fri Aug 24 21:39:24 2007 New Revision: 41394 URL: http://llvm.org/viewvc/llvm-project?rev=41394&view=rev Log: Move exit condition and exit branch from exiting block into loop header and dominator info. This avoid execution of dead iteration. Loop is already filter in the beginning such that this change is safe. Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp?rev=41394&r1=41393&r2=41394&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopIndexSplit.cpp Fri Aug 24 21:39:24 2007 @@ -126,6 +126,24 @@ /// based on split value. void calculateLoopBounds(SplitInfo &SD); + /// updatePHINodes - CFG has been changed. + /// Before + /// - ExitBB's single predecessor was Latch + /// - Latch's second successor was Header + /// Now + /// - ExitBB's single predecessor was Header + /// - Latch's one and only successor was Header + /// + /// Update ExitBB PHINodes' to reflect this change. + void updatePHINodes(BasicBlock *ExitBB, BasicBlock *Latch, + BasicBlock *Header, + PHINode *IV, Instruction *IVIncrement); + + /// moveExitCondition - Move exit condition EC into split condition block CondBB. + void moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB, + BasicBlock *ExitBB, ICmpInst *EC, ICmpInst *SC, + PHINode *IV, Instruction *IVAdd, Loop *LP); + /// splitLoop - Split current loop L in two loops using split information /// SD. Update dominator information. Maintain LCSSA form. bool splitLoop(SplitInfo &SD); @@ -987,6 +1005,7 @@ //[*] Clone loop. DenseMap ValueMap; Loop *BLoop = CloneLoop(L, LPM, LI, ValueMap, this); + Loop *ALoop = L; BasicBlock *B_Header = BLoop->getHeader(); //[*] ALoop's exiting edge BLoop's header. @@ -1110,5 +1129,141 @@ B_BR->setUnconditionalDest(B_ActiveBranch); removeBlocks(B_InactiveBranch, BLoop, B_ActiveBranch); + BasicBlock *A_Header = L->getHeader(); + if (A_ExitingBlock == A_Header) + return true; + + //[*] Move exit condition into split condition block to avoid + // executing dead loop iteration. + ICmpInst *B_ExitCondition = cast(ValueMap[ExitCondition]); + Instruction *B_IndVarIncrement = cast(ValueMap[IndVarIncrement]); + ICmpInst *B_SplitCondition = cast(ValueMap[SD.SplitCondition]); + + moveExitCondition(A_SplitCondBlock, A_ActiveBranch, A_ExitBlock, ExitCondition, + SD.SplitCondition, IndVar, IndVarIncrement, ALoop); + + moveExitCondition(B_SplitCondBlock, B_ActiveBranch, B_ExitBlock, B_ExitCondition, + B_SplitCondition, B_IndVar, B_IndVarIncrement, BLoop); + return true; } + +// moveExitCondition - Move exit condition EC into split condition block CondBB. +void LoopIndexSplit::moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB, + BasicBlock *ExitBB, ICmpInst *EC, ICmpInst *SC, + PHINode *IV, Instruction *IVAdd, Loop *LP) { + + BasicBlock *ExitingBB = EC->getParent(); + Instruction *CurrentBR = CondBB->getTerminator(); + + // Move exit condition into split condition block. + EC->moveBefore(CurrentBR); + EC->setOperand(ExitValueNum == 0 ? 1 : 0, IV); + + // Move exiting block's branch into split condition block. Update its branch + // destination. + BranchInst *ExitingBR = cast(ExitingBB->getTerminator()); + ExitingBR->moveBefore(CurrentBR); + if (ExitingBR->getSuccessor(0) == ExitBB) + ExitingBR->setSuccessor(1, ActiveBB); + else + ExitingBR->setSuccessor(0, ActiveBB); + + // Remove split condition and current split condition branch. + SC->eraseFromParent(); + CurrentBR->eraseFromParent(); + + // Connect exiting block to split condition block. + new BranchInst(CondBB, ExitingBB); + + // Update PHINodes + updatePHINodes(ExitBB, ExitingBB, CondBB, IV, IVAdd); + + // Fix dominator info. + // ExitBB is now dominated by CondBB + DT->changeImmediateDominator(ExitBB, CondBB); + DF->changeImmediateDominator(ExitBB, CondBB, DT); + + // Basicblocks dominated by ActiveBB may have ExitingBB or + // a basic block outside the loop in their DF list. If so, + // replace it with CondBB. + DomTreeNode *Node = DT->getNode(ActiveBB); + for (df_iterator DI = df_begin(Node), DE = df_end(Node); + DI != DE; ++DI) { + BasicBlock *BB = DI->getBlock(); + DominanceFrontier::iterator BBDF = DF->find(BB); + DominanceFrontier::DomSetType::iterator DomSetI = BBDF->second.begin(); + DominanceFrontier::DomSetType::iterator DomSetE = BBDF->second.end(); + while (DomSetI != DomSetE) { + DominanceFrontier::DomSetType::iterator CurrentItr = DomSetI; + ++DomSetI; + BasicBlock *DFBB = *CurrentItr; + if (DFBB == ExitingBB || !L->contains(DFBB)) { + BBDF->second.erase(DFBB); + BBDF->second.insert(CondBB); + } + } + } +} + +/// updatePHINodes - CFG has been changed. +/// Before +/// - ExitBB's single predecessor was Latch +/// - Latch's second successor was Header +/// Now +/// - ExitBB's single predecessor was Header +/// - Latch's one and only successor was Header +/// +/// Update ExitBB PHINodes' to reflect this change. +void LoopIndexSplit::updatePHINodes(BasicBlock *ExitBB, BasicBlock *Latch, + BasicBlock *Header, + PHINode *IV, Instruction *IVIncrement) { + + for (BasicBlock::iterator BI = ExitBB->begin(), BE = ExitBB->end(); + BI != BE; ++BI) { + PHINode *PN = dyn_cast(BI); + if (!PN) + break; + + Value *V = PN->getIncomingValueForBlock(Latch); + if (PHINode *PHV = dyn_cast(V)) { + // PHV is in Latch. PHV has two uses, one use is in ExitBB PHINode + // (i.e. PN :)). + // The second use is in Header and it is new incoming value for PN. + PHINode *U1 = NULL; + PHINode *U2 = NULL; + Value *NewV = NULL; + for (Value::use_iterator UI = PHV->use_begin(), E = PHV->use_end(); + UI != E; ++UI) { + if (!U1) + U1 = cast(*UI); + else if (!U2) + U2 = cast(*UI); + else + assert ( 0 && "Unexpected third use of this PHINode"); + } + assert (U1 && U2 && "Unable to find two uses"); + + if (U1->getParent() == Header) + NewV = U1; + else + NewV = U2; + PN->addIncoming(NewV, Header); + + } else if (Instruction *PHI = dyn_cast(V)) { + // If this instruction is IVIncrement then IV is new incoming value + // from header otherwise this instruction must be incoming value from + // header because loop is in LCSSA form. + if (PHI == IVIncrement) + PN->addIncoming(IV, Header); + else + PN->addIncoming(V, Header); + } else + // Otherwise this is an incoming value from header because loop is in + // LCSSA form. + PN->addIncoming(V, Header); + + // Remove incoming value from Latch. + PN->removeIncomingValue(Latch); + } +} From dalej at apple.com Sat Aug 25 00:08:13 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 24 Aug 2007 22:08:13 -0700 Subject: [llvm-commits] [patch] call libc memcpy/memset for big arrays In-Reply-To: References: <38a0d8450708240444y11d4b93esde577f1c60717f4d@mail.gmail.com> Message-ID: <7370919C-475C-4161-AAE3-2D483D2E19BD@apple.com> On Aug 24, 2007, at 6:15 PM, Chris Lattner wrote: > > On Aug 24, 2007, at 4:44 AM, Rafael Espindola wrote: > >> Currently we expand a memcpy/memset node to a call to the libc >> implementation if >> >> if ((Align & 3) != 0 || >> (I && I->getValue() < Subtarget->getMinRepStrSizeThreshold >> ())) { >> >> Shouldn't this be a ">". The libc memcpy/memset are very fast for >> big arrays. Do you have data to support this? It is dependent on the OS (well libc really) and target CPU for sure. > Yep, that makes sense to me! Please commit. > > Dale, please review the commit when you get a chance, Intuitively it looks OK. I'd like to see numbers, but I doubt that spending a lot of time on this is productive. I've spent way too much time playing with the heuristics for memcpy expansion. My firmest conclusion is that, whatever the compiler does, somebody will supply an example where it is better to do something else.:) The situation is especially bad on x86 since different things are optimal for different CPUs, and compiled code will typically run on more than one CPU. Here are some numbers from the last time I looked at it: http://gcc.gnu.org/ml/gcc-patches/2005-08/msg01614.html On that CPU and OS (Darwin 10.4, IIRC), it was never right to use rep/ mov, and the library function didn't look too good compared to repeated lod/sto. ymmv. > -Chris > >> If I compile >> >> --------------------------------------- >> #include >> void f1(long *a, long *b) { >> memcpy(a, b, 8 * 16); >> } >> >> void f2(long *a, long *b) { >> memcpy(a, b, 8 * 32); >> } >> --------------------------------------- >> >> with gcc 4.2 (-O2), it will call memcpy for f2 and not for f1. >> >> Cheers, >> -- >> Rafael Avila de Espindola >> >> Google Ireland Ltd. >> Gordon House >> Barrow Street >> Dublin 4 >> Ireland >> >> Registered in Dublin, Ireland >> Registration Number: 368047 >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Sat Aug 25 17:10:57 2007 From: dalej at apple.com (Dale Johannesen) Date: Sat, 25 Aug 2007 22:10:57 -0000 Subject: [llvm-commits] [llvm] r41407 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200708252210.l7PMAvVp024914@zion.cs.uiuc.edu> Author: johannes Date: Sat Aug 25 17:10:57 2007 New Revision: 41407 URL: http://llvm.org/viewvc/llvm-project?rev=41407&view=rev Log: Add APFloat interface to ConstantFPSDNode. Change over uses in DAGCombiner. Fix interfaces to work with APFloats. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=41407&r1=41406&r2=41407&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Sat Aug 25 17:10:57 2007 @@ -1151,17 +1151,36 @@ friend class SelectionDAG; ConstantFPSDNode(bool isTarget, double val, MVT::ValueType VT) : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, - getSDVTList(VT)), Value(APFloat(val)) { + getSDVTList(VT)), + Value(VT==MVT::f64 ? APFloat(val) : APFloat((float)val)) { + } + ConstantFPSDNode(bool isTarget, APFloat val, MVT::ValueType VT) + : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, + getSDVTList(VT)), Value(val) { } public: - double getValue() const { return Value.convertToDouble(); } + // Longterm plan: replace all uses of getValue with getValueAPF, remove + // getValue, rename getValueAPF to getValue. + double getValue() const { + if ( getValueType(0)==MVT::f64) + return Value.convertToDouble(); + else + return Value.convertToFloat(); + } + APFloat getValueAPF() const { return Value; } /// isExactlyValue - We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. - bool isExactlyValue(double V) const; + bool isExactlyValue(double V) const { + if (getValueType(0)==MVT::f64) + return isExactlyValue(APFloat(V)); + else + return isExactlyValue(APFloat((float)V)); + } + bool isExactlyValue(APFloat V) const; static bool classof(const ConstantFPSDNode *) { return true; } static bool classof(const SDNode *N) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=41407&r1=41406&r2=41407&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Aug 25 17:10:57 2007 @@ -3195,14 +3195,10 @@ return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1); if (N1CFP) { + APFloat V = N1CFP->getValueAPF(); // copysign(x, c1) -> fabs(x) iff ispos(c1) // copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1) - union { - double d; - int64_t i; - } u; - u.d = N1CFP->getValue(); - if (u.i >= 0) + if (!V.isNegative()) return DAG.getNode(ISD::FABS, VT, N0); else return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0)); @@ -3792,7 +3788,7 @@ default: assert(0 && "Unknown FP type"); case MVT::f32: if (!AfterLegalize || TLI.isTypeLegal(MVT::i32)) { - Tmp = DAG.getConstant(FloatToBits(CFP->getValue()), MVT::i32); + Tmp = DAG.getConstant(FloatToBits(CFP->getValueAPF().convertToFloat()), MVT::i32); return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); @@ -3800,7 +3796,7 @@ break; case MVT::f64: if (!AfterLegalize || TLI.isTypeLegal(MVT::i64)) { - Tmp = DAG.getConstant(DoubleToBits(CFP->getValue()), MVT::i64); + Tmp = DAG.getConstant(DoubleToBits(CFP->getValueAPF().convertToDouble()), MVT::i64); return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); @@ -3808,7 +3804,7 @@ // Many FP stores are not make apparent until after legalize, e.g. for // argument passing. Since this is so common, custom legalize the // 64-bit integer store into two 32-bit stores. - uint64_t Val = DoubleToBits(CFP->getValue()); + uint64_t Val = DoubleToBits(CFP->getValueAPF().convertToDouble()); SDOperand Lo = DAG.getConstant(Val & 0xFFFFFFFF, MVT::i32); SDOperand Hi = DAG.getConstant(Val >> 32, MVT::i32); if (!TLI.isLittleEndian()) std::swap(Lo, Hi); @@ -4365,7 +4361,7 @@ // Check to see if we can simplify the select into an fabs node if (ConstantFPSDNode *CFP = dyn_cast(N1)) { // Allow either -0.0 or 0.0 - if (CFP->getValue() == 0.0) { + if (CFP->getValueAPF().isZero()) { // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs if ((CC == ISD::SETGE || CC == ISD::SETGT) && N0 == N2 && N3.getOpcode() == ISD::FNEG && Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=41407&r1=41406&r2=41407&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Aug 25 17:10:57 2007 @@ -48,8 +48,8 @@ /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. -bool ConstantFPSDNode::isExactlyValue(double V) const { - return Value.bitwiseIsEqual(APFloat(V)); +bool ConstantFPSDNode::isExactlyValue(APFloat V) const { + return Value.bitwiseIsEqual(V); } //===----------------------------------------------------------------------===// @@ -669,7 +669,6 @@ return SDOperand(N, 0); } - SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT, bool isTarget) { assert(MVT::isFloatingPoint(VT) && "Cannot create integer FP constant!"); From dalej at apple.com Sat Aug 25 20:18:27 2007 From: dalej at apple.com (Dale Johannesen) Date: Sun, 26 Aug 2007 01:18:27 -0000 Subject: [llvm-commits] [llvm] r41409 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200708260118.l7Q1IRHc000357@zion.cs.uiuc.edu> Author: johannes Date: Sat Aug 25 20:18:27 2007 New Revision: 41409 URL: http://llvm.org/viewvc/llvm-project?rev=41409&view=rev Log: Revise per review comments. Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=41409&r1=41408&r2=41409&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Sat Aug 25 20:18:27 2007 @@ -1154,7 +1154,7 @@ getSDVTList(VT)), Value(VT==MVT::f64 ? APFloat(val) : APFloat((float)val)) { } - ConstantFPSDNode(bool isTarget, APFloat val, MVT::ValueType VT) + ConstantFPSDNode(bool isTarget, const APFloat& val, MVT::ValueType VT) : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, getSDVTList(VT)), Value(val) { } @@ -1168,7 +1168,7 @@ else return Value.convertToFloat(); } - APFloat getValueAPF() const { return Value; } + const APFloat& getValueAPF() const { return Value; } /// isExactlyValue - We don't rely on operator== working on double values, as /// it returns true for things that are clearly not equal, like -0.0 and 0.0. @@ -1180,7 +1180,7 @@ else return isExactlyValue(APFloat((float)V)); } - bool isExactlyValue(APFloat V) const; + bool isExactlyValue(const APFloat& V) const; static bool classof(const ConstantFPSDNode *) { return true; } static bool classof(const SDNode *N) { Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=41409&r1=41408&r2=41409&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sat Aug 25 20:18:27 2007 @@ -3195,7 +3195,7 @@ return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1); if (N1CFP) { - APFloat V = N1CFP->getValueAPF(); + const APFloat& V = N1CFP->getValueAPF(); // copysign(x, c1) -> fabs(x) iff ispos(c1) // copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1) if (!V.isNegative()) Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=41409&r1=41408&r2=41409&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Aug 25 20:18:27 2007 @@ -48,7 +48,7 @@ /// it returns true for things that are clearly not equal, like -0.0 and 0.0. /// As such, this method can be used to do an exact bit-for-bit comparison of /// two floating point values. -bool ConstantFPSDNode::isExactlyValue(APFloat V) const { +bool ConstantFPSDNode::isExactlyValue(const APFloat& V) const { return Value.bitwiseIsEqual(V); } From resistor at mac.com Sun Aug 26 16:14:48 2007 From: resistor at mac.com (Owen Anderson) Date: Sun, 26 Aug 2007 21:14:48 -0000 Subject: [llvm-commits] [llvm] r41456 - /llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Message-ID: <200708262114.l7QLEmtO024173@zion.cs.uiuc.edu> Author: resistor Date: Sun Aug 26 16:14:47 2007 New Revision: 41456 URL: http://llvm.org/viewvc/llvm-project?rev=41456&view=rev Log: Don't DSe volatile stores. Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=41456&r1=41455&r2=41456&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Sun Aug 26 16:14:47 2007 @@ -111,9 +111,12 @@ continue; Value* pointer = 0; - if (StoreInst* S = dyn_cast(BBI)) - pointer = S->getPointerOperand(); - else + if (StoreInst* S = dyn_cast(BBI)) { + if (!S->isVolatile()) + pointer = S->getPointerOperand(); + else + continue; + } else pointer = cast(BBI)->getPointerOperand(); StoreInst*& last = lastStore[pointer]; @@ -194,6 +197,8 @@ StoreInst* dependency = dyn_cast(dep); if (!dependency) return false; + else if (dependency->isVolatile()) + return false; Value* depPointer = dependency->getPointerOperand(); const Type* depType = dependency->getOperand(0)->getType(); @@ -253,24 +258,26 @@ // If we find a store whose pointer is dead... if (StoreInst* S = dyn_cast(BBI)) { - Value* pointerOperand = S->getPointerOperand(); - // See through pointer-to-pointer bitcasts - TranslatePointerBitCasts(pointerOperand); + if (!S->isVolatile()) { + Value* pointerOperand = S->getPointerOperand(); + // See through pointer-to-pointer bitcasts + TranslatePointerBitCasts(pointerOperand); - if (deadPointers.count(pointerOperand)){ - // Remove it! - MD.removeInstruction(S); + if (deadPointers.count(pointerOperand)){ + // Remove it! + MD.removeInstruction(S); - // DCE instructions only used to calculate that store - if (Instruction* D = dyn_cast(S->getOperand(0))) - possiblyDead.insert(D); - if (Instruction* D = dyn_cast(S->getOperand(1))) - possiblyDead.insert(D); + // DCE instructions only used to calculate that store + if (Instruction* D = dyn_cast(S->getOperand(0))) + possiblyDead.insert(D); + if (Instruction* D = dyn_cast(S->getOperand(1))) + possiblyDead.insert(D); - BBI++; - S->eraseFromParent(); - NumFastStores++; - MadeChange = true; + BBI++; + S->eraseFromParent(); + NumFastStores++; + MadeChange = true; + } } continue; From asl at math.spbu.ru Sun Aug 26 16:43:30 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sun, 26 Aug 2007 21:43:30 -0000 Subject: [llvm-commits] [llvm] r41461 - in /llvm/trunk: lib/Transforms/Utils/PromoteMemoryToRegister.cpp test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll Message-ID: <200708262143.l7QLhU0s025336@zion.cs.uiuc.edu> Author: asl Date: Sun Aug 26 16:43:30 2007 New Revision: 41461 URL: http://llvm.org/viewvc/llvm-project?rev=41461&view=rev Log: Don't promote volatile loads/stores. This is needed (for example) to handle setjmp/longjmp properly. This fixes PR1520. Added: llvm/trunk/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Modified: llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp?rev=41461&r1=41460&r2=41461&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/PromoteMemoryToRegister.cpp Sun Aug 26 16:43:30 2007 @@ -63,14 +63,17 @@ // FIXME: If the memory unit is of pointer or integer type, we can permit // assignments to subsections of the memory unit. - // Only allow direct loads and stores... + // Only allow direct and non-volatile loads and stores... for (Value::use_const_iterator UI = AI->use_begin(), UE = AI->use_end(); UI != UE; ++UI) // Loop over all of the uses of the alloca - if (isa(*UI)) { - // noop + if (const LoadInst *LI = dyn_cast(*UI)) { + if (LI->isVolatile()) + return false; } else if (const StoreInst *SI = dyn_cast(*UI)) { if (SI->getOperand(0) == AI) return false; // Don't allow a store OF the AI, only INTO the AI. + if (SI->isVolatile()) + return false; } else { return false; // Not a load or store. } Added: llvm/trunk/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll?rev=41461&view=auto ============================================================================== --- llvm/trunk/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll (added) +++ llvm/trunk/test/Transforms/Mem2Reg/2007-08-27-VolatileLoadsStores.ll Sun Aug 26 16:43:30 2007 @@ -0,0 +1,47 @@ +; RUN: llvm-as < %s | opt -std-compile-opts | llvm-dis | grep volatile | count 3 +; PR1520 +; Don't promote volatile loads/stores. This is really needed to handle setjmp/lonjmp properly. + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + %struct.__jmp_buf_tag = type { [6 x i32], i32, %struct.__sigset_t } + %struct.__sigset_t = type { [32 x i32] } + at j = external global [1 x %struct.__jmp_buf_tag] ; <[1 x %struct.__jmp_buf_tag]*> [#uses=1] + +define i32 @f() { +entry: + %retval = alloca i32, align 4 ; [#uses=2] + %v = alloca i32, align 4 ; [#uses=3] + %tmp = alloca i32, align 4 ; [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + volatile store i32 0, i32* %v, align 4 + %tmp1 = call i32 @_setjmp( %struct.__jmp_buf_tag* getelementptr ([1 x %struct.__jmp_buf_tag]* @j, i32 0, i32 0) ) ; [#uses=1] + %tmp2 = icmp ne i32 %tmp1, 0 ; [#uses=1] + %tmp23 = zext i1 %tmp2 to i8 ; [#uses=1] + %toBool = icmp ne i8 %tmp23, 0 ; [#uses=1] + br i1 %toBool, label %bb, label %bb5 + +bb: ; preds = %entry + %tmp4 = volatile load i32* %v, align 4 ; [#uses=1] + store i32 %tmp4, i32* %tmp, align 4 + br label %bb6 + +bb5: ; preds = %entry + volatile store i32 1, i32* %v, align 4 + call void @g( ) + store i32 0, i32* %tmp, align 4 + br label %bb6 + +bb6: ; preds = %bb5, %bb + %tmp7 = load i32* %tmp, align 4 ; [#uses=1] + store i32 %tmp7, i32* %retval, align 4 + br label %return + +return: ; preds = %bb6 + %retval8 = load i32* %retval ; [#uses=1] + ret i32 %retval8 +} + +declare i32 @_setjmp(%struct.__jmp_buf_tag*) + +declare void @g()