[llvm-commits] [llvm] r138724 - in /llvm/trunk: lib/CodeGen/AsmPrinter/AsmPrinter.cpp test/CodeGen/X86/2011-08-29-InitOrder.ll

Eli Friedman eli.friedman at gmail.com
Wed Aug 31 10:14:07 PDT 2011


On Sun, Aug 28, 2011 at 6:17 AM, Duncan Sands <baldrick at free.fr> wrote:
> Author: baldrick
> Date: Sun Aug 28 08:17:22 2011
> New Revision: 138724
>
> URL: http://llvm.org/viewvc/llvm-project?rev=138724&view=rev
> Log:
> Fix PR5329: pay attention to constructor/destructor priority
> when outputting them.  With this, the entire LLVM testsuite
> passes when built with dragonegg.
>
> Added:
>    llvm/trunk/test/CodeGen/X86/2011-08-29-InitOrder.ll
> Modified:
>    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=138724&r1=138723&r2=138724&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Sun Aug 28 08:17:22 2011
> @@ -1228,22 +1228,45 @@
>   }
>  }
>
> -/// EmitXXStructorList - Emit the ctor or dtor list.  This just prints out the
> -/// function pointers, ignoring the init priority.
> +typedef std::pair<int, Constant*> Structor;
> +
> +static bool priority_order(const Structor& lhs, const Structor& rhs)
> +{
> +  return lhs.first < rhs.first;
> +}
> +
> +/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
> +/// priority.
>  void AsmPrinter::EmitXXStructorList(const Constant *List) {
>   // Should be an array of '{ int, void ()* }' structs.  The first value is the
> -  // init priority, which we ignore.
> +  // init priority.
>   if (!isa<ConstantArray>(List)) return;
> -  const ConstantArray *InitList = cast<ConstantArray>(List);
> -  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
> -    if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){
> -      if (CS->getNumOperands() != 2) return;  // Not array of 2-element structs.
> -
> -      if (CS->getOperand(1)->isNullValue())
> -        return;  // Found a null terminator, exit printing.
> -      // Emit the function pointer.
> -      EmitGlobalConstant(CS->getOperand(1));
> -    }
> +
> +  // Sanity check the structors list.
> +  const ConstantArray *InitList = dyn_cast<ConstantArray>(List);
> +  if (!InitList) return; // Not an array!
> +  StructType *ETy = dyn_cast<StructType>(InitList->getType()->getElementType());
> +  if (!ETy || ETy->getNumElements() != 2) return; // Not an array of pairs!
> +  if (!isa<IntegerType>(ETy->getTypeAtIndex(0U)) ||
> +      !isa<PointerType>(ETy->getTypeAtIndex(1U))) return; // Not (int, ptr).
> +
> +  // Gather the structors in a form that's convenient for sorting by priority.
> +  SmallVector<Structor, 8> Structors;
> +  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
> +    ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i));
> +    if (!CS) continue; // Malformed.
> +    if (CS->getOperand(1)->isNullValue())
> +      break;  // Found a null terminator, skip the rest.
> +    ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
> +    if (!Priority) continue; // Malformed.
> +    Structors.push_back(std::make_pair(Priority->getLimitedValue(65535),
> +                                       CS->getOperand(1)));
> +  }
> +
> +  // Emit the function pointers in reverse priority order.
> +  std::sort(Structors.rbegin(), Structors.rend(), priority_order);
> +  for (unsigned i = 0, e = Structors.size(); i != e; ++i)
> +    EmitGlobalConstant(Structors[i].second);

Doesn't this need to use std::stable_sort()?

-Eli




More information about the llvm-commits mailing list