[llvm-commits] [llvm] r105528 - in /llvm/trunk: lib/Transforms/IPO/PartialSpecialization.cpp test/Transforms/PartialSpecialize/ test/Transforms/PartialSpecialize/dg.exp test/Transforms/PartialSpecialize/two-specializations.ll

Kenneth Uildriks kennethuil at gmail.com
Thu Jun 24 07:26:24 PDT 2010


Sorry, I was away for a little while.  I'll look at it today.

On Wed, Jun 23, 2010 at 1:03 PM, Daniel Dunbar <daniel at zuster.org> wrote:
> Hi Kenneth,
>
> This test is failing on llvm-arm-linux. It looks to me like the order
> of the partial specialization numbering isn't deterministic?
>
> Failure is here:
>  http://google1.osuosl.org:8011/builders/llvm-arm-linux/builds/3516/steps/test-llvm/logs/two-specializations.ll
>
> Can you take a look?
>
>  - Daniel
>
> On Sat, Jun 5, 2010 at 7:50 AM, Kenneth Uildriks <kennethuil at gmail.com> wrote:
>> Author: kennethuil
>> Date: Sat Jun  5 09:50:21 2010
>> New Revision: 105528
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=105528&view=rev
>> Log:
>> Partial specialization was not checking the callsite to make sure it was using the same constants as the specialization, leading to calls to the wrong specialization.  Patch by Takumi Nakamura\!
>>
>> Added:
>>    llvm/trunk/test/Transforms/PartialSpecialize/
>>    llvm/trunk/test/Transforms/PartialSpecialize/dg.exp
>>    llvm/trunk/test/Transforms/PartialSpecialize/two-specializations.ll
>> Modified:
>>    llvm/trunk/lib/Transforms/IPO/PartialSpecialization.cpp
>>
>> Modified: llvm/trunk/lib/Transforms/IPO/PartialSpecialization.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PartialSpecialization.cpp?rev=105528&r1=105527&r2=105528&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/IPO/PartialSpecialization.cpp (original)
>> +++ llvm/trunk/lib/Transforms/IPO/PartialSpecialization.cpp Sat Jun  5 09:50:21 2010
>> @@ -32,6 +32,10 @@
>>  using namespace llvm;
>>
>>  STATISTIC(numSpecialized, "Number of specialized functions created");
>> +STATISTIC(numReplaced, "Number of callers replaced by specialization");
>> +
>> +// Maximum number of arguments markable interested
>> +static const int MaxInterests = 6;
>>
>>  // Call must be used at least occasionally
>>  static const int CallsMin = 5;
>> @@ -40,8 +44,9 @@
>>  static const double ConstValPercent = .1;
>>
>>  namespace {
>> +  typedef SmallVector<int, MaxInterests> InterestingArgVector;
>>   class PartSpec : public ModulePass {
>> -    void scanForInterest(Function&, SmallVector<int, 6>&);
>> +    void scanForInterest(Function&, InterestingArgVector&);
>>     int scanDistribution(Function&, int, std::map<Constant*, int>&);
>>   public :
>>     static char ID; // Pass identification, replacement for typeid
>> @@ -61,11 +66,13 @@
>>  SpecializeFunction(Function* F,
>>                    DenseMap<const Value*, Value*>& replacements) {
>>   // arg numbers of deleted arguments
>> -  DenseSet<unsigned> deleted;
>> +  DenseMap<unsigned, const Argument*> deleted;
>>   for (DenseMap<const Value*, Value*>::iterator
>>          repb = replacements.begin(), repe = replacements.end();
>> -       repb != repe; ++repb)
>> -    deleted.insert(cast<Argument>(repb->first)->getArgNo());
>> +       repb != repe; ++repb) {
>> +    Argument const *arg = cast<const Argument>(repb->first);
>> +    deleted[arg->getArgNo()] = arg;
>> +  }
>>
>>   Function* NF = CloneFunction(F, replacements);
>>   NF->setLinkage(GlobalValue::InternalLinkage);
>> @@ -80,9 +87,23 @@
>>       if (CS.getCalledFunction() == F) {
>>
>>         SmallVector<Value*, 6> args;
>> -        for (unsigned x = 0; x < CS.arg_size(); ++x)
>> -          if (!deleted.count(x))
>> -            args.push_back(CS.getArgument(x));
>> +        // Assemble the non-specialized arguments for the updated callsite.
>> +        // In the process, make sure that the specialized arguments are
>> +        // constant and match the specialization.  If that's not the case,
>> +        // this callsite needs to call the original or some other
>> +        // specialization; don't change it here.
>> +        CallSite::arg_iterator as = CS.arg_begin(), ae = CS.arg_end();
>> +        for (CallSite::arg_iterator ai = as; ai != ae; ++ai) {
>> +          DenseMap<unsigned, const Argument*>::iterator delit = deleted.find(
>> +            std::distance(as, ai));
>> +          if (delit == deleted.end())
>> +            args.push_back(cast<Value>(ai));
>> +          else {
>> +            Constant *ci = dyn_cast<Constant>(ai);
>> +            if (!(ci && ci == replacements[delit->second]))
>> +              goto next_use;
>> +          }
>> +        }
>>         Value* NCall;
>>         if (CallInst *CI = dyn_cast<CallInst>(i)) {
>>           NCall = CallInst::Create(NF, args.begin(), args.end(),
>> @@ -99,8 +120,11 @@
>>         }
>>         CS.getInstruction()->replaceAllUsesWith(NCall);
>>         CS.getInstruction()->eraseFromParent();
>> +        ++numReplaced;
>>       }
>>     }
>> +  next_use:
>> +    ;
>>   }
>>   return NF;
>>  }
>> @@ -111,7 +135,7 @@
>>   for (Module::iterator I = M.begin(); I != M.end(); ++I) {
>>     Function &F = *I;
>>     if (F.isDeclaration() || F.mayBeOverridden()) continue;
>> -    SmallVector<int, 6> interestingArgs;
>> +    InterestingArgVector interestingArgs;
>>     scanForInterest(F, interestingArgs);
>>
>>     // Find the first interesting Argument that we can specialize on
>> @@ -143,7 +167,7 @@
>>
>>  /// scanForInterest - This function decides which arguments would be worth
>>  /// specializing on.
>> -void PartSpec::scanForInterest(Function& F, SmallVector<int, 6>& args) {
>> +void PartSpec::scanForInterest(Function& F, InterestingArgVector& args) {
>>   for(Function::arg_iterator ii = F.arg_begin(), ee = F.arg_end();
>>       ii != ee; ++ii) {
>>     for(Value::use_iterator ui = ii->use_begin(), ue = ii->use_end();
>>
>> Added: llvm/trunk/test/Transforms/PartialSpecialize/dg.exp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/PartialSpecialize/dg.exp?rev=105528&view=auto
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/PartialSpecialize/dg.exp (added)
>> +++ llvm/trunk/test/Transforms/PartialSpecialize/dg.exp Sat Jun  5 09:50:21 2010
>> @@ -0,0 +1,3 @@
>> +load_lib llvm.exp
>> +
>> +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
>>
>> Added: llvm/trunk/test/Transforms/PartialSpecialize/two-specializations.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/PartialSpecialize/two-specializations.ll?rev=105528&view=auto
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/PartialSpecialize/two-specializations.ll (added)
>> +++ llvm/trunk/test/Transforms/PartialSpecialize/two-specializations.ll Sat Jun  5 09:50:21 2010
>> @@ -0,0 +1,32 @@
>> +; If there are two specializations of a function, make sure each callsite
>> +; calls the right one.
>> +;
>> +; RUN: opt -S -partialspecialization %s | FileCheck %s
>> +declare void @callback1()
>> +declare void @callback2()
>> +
>> +define internal void @UseCallback(void()* %pCallback) {
>> +  call void %pCallback()
>> +  ret void
>> +}
>> +
>> +define void @foo(void()* %pNonConstCallback)
>> +{
>> +Entry:
>> +; CHECK: Entry
>> +; CHECK-NEXT: call void @UseCallback1()
>> +; CHECK-NEXT: call void @UseCallback1()
>> +; CHECK-NEXT: call void @UseCallback2()
>> +; CHECK-NEXT: call void @UseCallback(void ()* %pNonConstCallback)
>> +; CHECK-NEXT: call void @UseCallback1()
>> +; CHECK-NEXT: call void @UseCallback2()
>> +; CHECK-NEXT: call void @UseCallback2()
>> +  call void @UseCallback(void()* @callback1)
>> +  call void @UseCallback(void()* @callback1)
>> +  call void @UseCallback(void()* @callback2)
>> +  call void @UseCallback(void()* %pNonConstCallback)
>> +  call void @UseCallback(void()* @callback1)
>> +  call void @UseCallback(void()* @callback2)
>> +  call void @UseCallback(void()* @callback2)
>> +  ret void
>> +}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>




More information about the llvm-commits mailing list