[llvm-commits] [llvm] r153267 - /llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp

Dan Gohman gohman at apple.com
Thu Mar 22 16:50:36 PDT 2012


This commit is enhancing already implemented code.

Dan

On Mar 22, 2012, at 4:43 PM, Jim Grosbach wrote:

> Gratuitous nitpick of the week: Function names start w/ lower case these days.
> 
> -j
> On Mar 22, 2012, at 11:24 AM, Dan Gohman <gohman at apple.com> wrote:
> 
>> Author: djg
>> Date: Thu Mar 22 13:24:56 2012
>> New Revision: 153267
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=153267&view=rev
>> Log:
>> Refactor the code for visiting instructions out into helper functions.
>> 
>> Modified:
>>   llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
>> 
>> Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=153267&r1=153266&r2=153267&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Thu Mar 22 13:24:56 2012
>> @@ -1678,9 +1678,15 @@
>>    void CheckForCFGHazards(const BasicBlock *BB,
>>                            DenseMap<const BasicBlock *, BBState> &BBStates,
>>                            BBState &MyStates) const;
>> +    bool VisitInstructionBottomUp(Instruction *Inst,
>> +                                  MapVector<Value *, RRInfo> &Retains,
>> +                                  BBState &MyStates);
>>    bool VisitBottomUp(BasicBlock *BB,
>>                       DenseMap<const BasicBlock *, BBState> &BBStates,
>>                       MapVector<Value *, RRInfo> &Retains);
>> +    bool VisitInstructionTopDown(Instruction *Inst,
>> +                                 DenseMap<Value *, RRInfo> &Releases,
>> +                                 BBState &MyStates);
>>    bool VisitTopDown(BasicBlock *BB,
>>                      DenseMap<const BasicBlock *, BBState> &BBStates,
>>                      DenseMap<Value *, RRInfo> &Releases);
>> @@ -2516,6 +2522,153 @@
>> }
>> 
>> bool
>> +ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst,
>> +                                     MapVector<Value *, RRInfo> &Retains,
>> +                                     BBState &MyStates) {
>> +  bool NestingDetected = false;
>> +  InstructionClass Class = GetInstructionClass(Inst);
>> +  const Value *Arg = 0;
>> +
>> +  switch (Class) {
>> +  case IC_Release: {
>> +    Arg = GetObjCArg(Inst);
>> +
>> +    PtrState &S = MyStates.getPtrBottomUpState(Arg);
>> +
>> +    // If we see two releases in a row on the same pointer. If so, make
>> +    // a note, and we'll cicle back to revisit it after we've
>> +    // hopefully eliminated the second release, which may allow us to
>> +    // eliminate the first release too.
>> +    // Theoretically we could implement removal of nested retain+release
>> +    // pairs by making PtrState hold a stack of states, but this is
>> +    // simple and avoids adding overhead for the non-nested case.
>> +    if (S.GetSeq() == S_Release || S.GetSeq() == S_MovableRelease)
>> +      NestingDetected = true;
>> +
>> +    S.RRI.clear();
>> +
>> +    MDNode *ReleaseMetadata = Inst->getMetadata(ImpreciseReleaseMDKind);
>> +    S.SetSeq(ReleaseMetadata ? S_MovableRelease : S_Release);
>> +    S.RRI.ReleaseMetadata = ReleaseMetadata;
>> +    S.RRI.KnownSafe = S.IsKnownNested() || S.IsKnownIncremented();
>> +    S.RRI.IsTailCallRelease = cast<CallInst>(Inst)->isTailCall();
>> +    S.RRI.Calls.insert(Inst);
>> +
>> +    S.IncrementRefCount();
>> +    S.IncrementNestCount();
>> +    break;
>> +  }
>> +  case IC_RetainBlock:
>> +    // An objc_retainBlock call with just a use may need to be kept,
>> +    // because it may be copying a block from the stack to the heap.
>> +    if (!IsRetainBlockOptimizable(Inst))
>> +      break;
>> +    // FALLTHROUGH
>> +  case IC_Retain:
>> +  case IC_RetainRV: {
>> +    Arg = GetObjCArg(Inst);
>> +
>> +    PtrState &S = MyStates.getPtrBottomUpState(Arg);
>> +    S.DecrementRefCount();
>> +    S.SetAtLeastOneRefCount();
>> +    S.DecrementNestCount();
>> +
>> +    switch (S.GetSeq()) {
>> +    case S_Stop:
>> +    case S_Release:
>> +    case S_MovableRelease:
>> +    case S_Use:
>> +      S.RRI.ReverseInsertPts.clear();
>> +      // FALL THROUGH
>> +    case S_CanRelease:
>> +      // Don't do retain+release tracking for IC_RetainRV, because it's
>> +      // better to let it remain as the first instruction after a call.
>> +      if (Class != IC_RetainRV) {
>> +        S.RRI.IsRetainBlock = Class == IC_RetainBlock;
>> +        Retains[Inst] = S.RRI;
>> +      }
>> +      S.ClearSequenceProgress();
>> +      break;
>> +    case S_None:
>> +      break;
>> +    case S_Retain:
>> +      llvm_unreachable("bottom-up pointer in retain state!");
>> +    }
>> +    return NestingDetected;
>> +  }
>> +  case IC_AutoreleasepoolPop:
>> +    // Conservatively, clear MyStates for all known pointers.
>> +    MyStates.clearBottomUpPointers();
>> +    return NestingDetected;
>> +  case IC_AutoreleasepoolPush:
>> +  case IC_None:
>> +    // These are irrelevant.
>> +    return NestingDetected;
>> +  default:
>> +    break;
>> +  }
>> +
>> +  // Consider any other possible effects of this instruction on each
>> +  // pointer being tracked.
>> +  for (BBState::ptr_iterator MI = MyStates.bottom_up_ptr_begin(),
>> +       ME = MyStates.bottom_up_ptr_end(); MI != ME; ++MI) {
>> +    const Value *Ptr = MI->first;
>> +    if (Ptr == Arg)
>> +      continue; // Handled above.
>> +    PtrState &S = MI->second;
>> +    Sequence Seq = S.GetSeq();
>> +
>> +    // Check for possible releases.
>> +    if (CanAlterRefCount(Inst, Ptr, PA, Class)) {
>> +      S.DecrementRefCount();
>> +      switch (Seq) {
>> +      case S_Use:
>> +        S.SetSeq(S_CanRelease);
>> +        continue;
>> +      case S_CanRelease:
>> +      case S_Release:
>> +      case S_MovableRelease:
>> +      case S_Stop:
>> +      case S_None:
>> +        break;
>> +      case S_Retain:
>> +        llvm_unreachable("bottom-up pointer in retain state!");
>> +      }
>> +    }
>> +
>> +    // Check for possible direct uses.
>> +    switch (Seq) {
>> +    case S_Release:
>> +    case S_MovableRelease:
>> +      if (CanUse(Inst, Ptr, PA, Class)) {
>> +        assert(S.RRI.ReverseInsertPts.empty());
>> +        S.RRI.ReverseInsertPts.insert(Inst);
>> +        S.SetSeq(S_Use);
>> +      } else if (Seq == S_Release &&
>> +                 (Class == IC_User || Class == IC_CallOrUser)) {
>> +        // Non-movable releases depend on any possible objc pointer use.
>> +        S.SetSeq(S_Stop);
>> +        assert(S.RRI.ReverseInsertPts.empty());
>> +        S.RRI.ReverseInsertPts.insert(Inst);
>> +      }
>> +      break;
>> +    case S_Stop:
>> +      if (CanUse(Inst, Ptr, PA, Class))
>> +        S.SetSeq(S_Use);
>> +      break;
>> +    case S_CanRelease:
>> +    case S_Use:
>> +    case S_None:
>> +      break;
>> +    case S_Retain:
>> +      llvm_unreachable("bottom-up pointer in retain state!");
>> +    }
>> +  }
>> +
>> +  return NestingDetected;
>> +}
>> +
>> +bool
>> ObjCARCOpt::VisitBottomUp(BasicBlock *BB,
>>                          DenseMap<const BasicBlock *, BBState> &BBStates,
>>                          MapVector<Value *, RRInfo> &Retains) {
>> @@ -2560,144 +2713,148 @@
>>  // Visit all the instructions, bottom-up.
>>  for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; --I) {
>>    Instruction *Inst = llvm::prior(I);
>> -    InstructionClass Class = GetInstructionClass(Inst);
>> -    const Value *Arg = 0;
>> +    NestingDetected |= VisitInstructionBottomUp(Inst, Retains, MyStates);
>> +  }
>> 
>> -    switch (Class) {
>> -    case IC_Release: {
>> -      Arg = GetObjCArg(Inst);
>> +  return NestingDetected;
>> +}
>> 
>> -      PtrState &S = MyStates.getPtrBottomUpState(Arg);
>> +bool
>> +ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst,
>> +                                    DenseMap<Value *, RRInfo> &Releases,
>> +                                    BBState &MyStates) {
>> +  bool NestingDetected = false;
>> +  InstructionClass Class = GetInstructionClass(Inst);
>> +  const Value *Arg = 0;
>> 
>> -      // If we see two releases in a row on the same pointer. If so, make
>> +  switch (Class) {
>> +  case IC_RetainBlock:
>> +    // An objc_retainBlock call with just a use may need to be kept,
>> +    // because it may be copying a block from the stack to the heap.
>> +    if (!IsRetainBlockOptimizable(Inst))
>> +      break;
>> +    // FALLTHROUGH
>> +  case IC_Retain:
>> +  case IC_RetainRV: {
>> +    Arg = GetObjCArg(Inst);
>> +
>> +    PtrState &S = MyStates.getPtrTopDownState(Arg);
>> +
>> +    // Don't do retain+release tracking for IC_RetainRV, because it's
>> +    // better to let it remain as the first instruction after a call.
>> +    if (Class != IC_RetainRV) {
>> +      // If we see two retains in a row on the same pointer. If so, make
>>      // a note, and we'll cicle back to revisit it after we've
>> -      // hopefully eliminated the second release, which may allow us to
>> -      // eliminate the first release too.
>> +      // hopefully eliminated the second retain, which may allow us to
>> +      // eliminate the first retain too.
>>      // Theoretically we could implement removal of nested retain+release
>>      // pairs by making PtrState hold a stack of states, but this is
>>      // simple and avoids adding overhead for the non-nested case.
>> -      if (S.GetSeq() == S_Release || S.GetSeq() == S_MovableRelease)
>> +      if (S.GetSeq() == S_Retain)
>>        NestingDetected = true;
>> 
>> +      S.SetSeq(S_Retain);
>>      S.RRI.clear();
>> -
>> -      MDNode *ReleaseMetadata = Inst->getMetadata(ImpreciseReleaseMDKind);
>> -      S.SetSeq(ReleaseMetadata ? S_MovableRelease : S_Release);
>> -      S.RRI.ReleaseMetadata = ReleaseMetadata;
>> -      S.RRI.KnownSafe = S.IsKnownNested() || S.IsKnownIncremented();
>> -      S.RRI.IsTailCallRelease = cast<CallInst>(Inst)->isTailCall();
>> +      S.RRI.IsRetainBlock = Class == IC_RetainBlock;
>> +      // Don't check S.IsKnownIncremented() here because it's not
>> +      // sufficient.
>> +      S.RRI.KnownSafe = S.IsKnownNested();
>>      S.RRI.Calls.insert(Inst);
>> +    }
>> 
>> -      S.IncrementRefCount();
>> -      S.IncrementNestCount();
>> +    S.SetAtLeastOneRefCount();
>> +    S.IncrementRefCount();
>> +    S.IncrementNestCount();
>> +    return NestingDetected;
>> +  }
>> +  case IC_Release: {
>> +    Arg = GetObjCArg(Inst);
>> +
>> +    PtrState &S = MyStates.getPtrTopDownState(Arg);
>> +    S.DecrementRefCount();
>> +    S.DecrementNestCount();
>> +
>> +    switch (S.GetSeq()) {
>> +    case S_Retain:
>> +    case S_CanRelease:
>> +      S.RRI.ReverseInsertPts.clear();
>> +      // FALL THROUGH
>> +    case S_Use:
>> +      S.RRI.ReleaseMetadata = Inst->getMetadata(ImpreciseReleaseMDKind);
>> +      S.RRI.IsTailCallRelease = cast<CallInst>(Inst)->isTailCall();
>> +      Releases[Inst] = S.RRI;
>> +      S.ClearSequenceProgress();
>>      break;
>> +    case S_None:
>> +      break;
>> +    case S_Stop:
>> +    case S_Release:
>> +    case S_MovableRelease:
>> +      llvm_unreachable("top-down pointer in release state!");
>>    }
>> -    case IC_RetainBlock:
>> -      // An objc_retainBlock call with just a use may need to be kept,
>> -      // because it may be copying a block from the stack to the heap.
>> -      if (!IsRetainBlockOptimizable(Inst))
>> -        break;
>> -      // FALLTHROUGH
>> -    case IC_Retain:
>> -    case IC_RetainRV: {
>> -      Arg = GetObjCArg(Inst);
>> +    break;
>> +  }
>> +  case IC_AutoreleasepoolPop:
>> +    // Conservatively, clear MyStates for all known pointers.
>> +    MyStates.clearTopDownPointers();
>> +    return NestingDetected;
>> +  case IC_AutoreleasepoolPush:
>> +  case IC_None:
>> +    // These are irrelevant.
>> +    return NestingDetected;
>> +  default:
>> +    break;
>> +  }
>> 
>> -      PtrState &S = MyStates.getPtrBottomUpState(Arg);
>> -      S.DecrementRefCount();
>> -      S.SetAtLeastOneRefCount();
>> -      S.DecrementNestCount();
>> +  // Consider any other possible effects of this instruction on each
>> +  // pointer being tracked.
>> +  for (BBState::ptr_iterator MI = MyStates.top_down_ptr_begin(),
>> +       ME = MyStates.top_down_ptr_end(); MI != ME; ++MI) {
>> +    const Value *Ptr = MI->first;
>> +    if (Ptr == Arg)
>> +      continue; // Handled above.
>> +    PtrState &S = MI->second;
>> +    Sequence Seq = S.GetSeq();
>> 
>> -      switch (S.GetSeq()) {
>> -      case S_Stop:
>> -      case S_Release:
>> -      case S_MovableRelease:
>> +    // Check for possible releases.
>> +    if (CanAlterRefCount(Inst, Ptr, PA, Class)) {
>> +      S.DecrementRefCount();
>> +      switch (Seq) {
>> +      case S_Retain:
>> +        S.SetSeq(S_CanRelease);
>> +        assert(S.RRI.ReverseInsertPts.empty());
>> +        S.RRI.ReverseInsertPts.insert(Inst);
>> +
>> +        // One call can't cause a transition from S_Retain to S_CanRelease
>> +        // and S_CanRelease to S_Use. If we've made the first transition,
>> +        // we're done.
>> +        continue;
>>      case S_Use:
>> -        S.RRI.ReverseInsertPts.clear();
>> -        // FALL THROUGH
>>      case S_CanRelease:
>> -        // Don't do retain+release tracking for IC_RetainRV, because it's
>> -        // better to let it remain as the first instruction after a call.
>> -        if (Class != IC_RetainRV) {
>> -          S.RRI.IsRetainBlock = Class == IC_RetainBlock;
>> -          Retains[Inst] = S.RRI;
>> -        }
>> -        S.ClearSequenceProgress();
>> -        break;
>>      case S_None:
>>        break;
>> -      case S_Retain:
>> -        llvm_unreachable("bottom-up pointer in retain state!");
>> -      }
>> -      continue;
>> -    }
>> -    case IC_AutoreleasepoolPop:
>> -      // Conservatively, clear MyStates for all known pointers.
>> -      MyStates.clearBottomUpPointers();
>> -      continue;
>> -    case IC_AutoreleasepoolPush:
>> -    case IC_None:
>> -      // These are irrelevant.
>> -      continue;
>> -    default:
>> -      break;
>> -    }
>> -
>> -    // Consider any other possible effects of this instruction on each
>> -    // pointer being tracked.
>> -    for (BBState::ptr_iterator MI = MyStates.bottom_up_ptr_begin(),
>> -         ME = MyStates.bottom_up_ptr_end(); MI != ME; ++MI) {
>> -      const Value *Ptr = MI->first;
>> -      if (Ptr == Arg)
>> -        continue; // Handled above.
>> -      PtrState &S = MI->second;
>> -      Sequence Seq = S.GetSeq();
>> -
>> -      // Check for possible releases.
>> -      if (CanAlterRefCount(Inst, Ptr, PA, Class)) {
>> -        S.DecrementRefCount();
>> -        switch (Seq) {
>> -        case S_Use:
>> -          S.SetSeq(S_CanRelease);
>> -          continue;
>> -        case S_CanRelease:
>> -        case S_Release:
>> -        case S_MovableRelease:
>> -        case S_Stop:
>> -        case S_None:
>> -          break;
>> -        case S_Retain:
>> -          llvm_unreachable("bottom-up pointer in retain state!");
>> -        }
>> -      }
>> -
>> -      // Check for possible direct uses.
>> -      switch (Seq) {
>> +      case S_Stop:
>>      case S_Release:
>>      case S_MovableRelease:
>> -        if (CanUse(Inst, Ptr, PA, Class)) {
>> -          assert(S.RRI.ReverseInsertPts.empty());
>> -          S.RRI.ReverseInsertPts.insert(Inst);
>> -          S.SetSeq(S_Use);
>> -        } else if (Seq == S_Release &&
>> -                   (Class == IC_User || Class == IC_CallOrUser)) {
>> -          // Non-movable releases depend on any possible objc pointer use.
>> -          S.SetSeq(S_Stop);
>> -          assert(S.RRI.ReverseInsertPts.empty());
>> -          S.RRI.ReverseInsertPts.insert(Inst);
>> -        }
>> -        break;
>> -      case S_Stop:
>> -        if (CanUse(Inst, Ptr, PA, Class))
>> -          S.SetSeq(S_Use);
>> -        break;
>> -      case S_CanRelease:
>> -      case S_Use:
>> -      case S_None:
>> -        break;
>> -      case S_Retain:
>> -        llvm_unreachable("bottom-up pointer in retain state!");
>> +        llvm_unreachable("top-down pointer in release state!");
>>      }
>>    }
>> +
>> +    // Check for possible direct uses.
>> +    switch (Seq) {
>> +    case S_CanRelease:
>> +      if (CanUse(Inst, Ptr, PA, Class))
>> +        S.SetSeq(S_Use);
>> +      break;
>> +    case S_Retain:
>> +    case S_Use:
>> +    case S_None:
>> +      break;
>> +    case S_Stop:
>> +    case S_Release:
>> +    case S_MovableRelease:
>> +      llvm_unreachable("top-down pointer in release state!");
>> +    }
>>  }
>> 
>>  return NestingDetected;
>> @@ -2751,138 +2908,7 @@
>>  // Visit all the instructions, top-down.
>>  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
>>    Instruction *Inst = I;
>> -    InstructionClass Class = GetInstructionClass(Inst);
>> -    const Value *Arg = 0;
>> -
>> -    switch (Class) {
>> -    case IC_RetainBlock:
>> -      // An objc_retainBlock call with just a use may need to be kept,
>> -      // because it may be copying a block from the stack to the heap.
>> -      if (!IsRetainBlockOptimizable(Inst))
>> -        break;
>> -      // FALLTHROUGH
>> -    case IC_Retain:
>> -    case IC_RetainRV: {
>> -      Arg = GetObjCArg(Inst);
>> -
>> -      PtrState &S = MyStates.getPtrTopDownState(Arg);
>> -
>> -      // Don't do retain+release tracking for IC_RetainRV, because it's
>> -      // better to let it remain as the first instruction after a call.
>> -      if (Class != IC_RetainRV) {
>> -        // If we see two retains in a row on the same pointer. If so, make
>> -        // a note, and we'll cicle back to revisit it after we've
>> -        // hopefully eliminated the second retain, which may allow us to
>> -        // eliminate the first retain too.
>> -        // Theoretically we could implement removal of nested retain+release
>> -        // pairs by making PtrState hold a stack of states, but this is
>> -        // simple and avoids adding overhead for the non-nested case.
>> -        if (S.GetSeq() == S_Retain)
>> -          NestingDetected = true;
>> -
>> -        S.SetSeq(S_Retain);
>> -        S.RRI.clear();
>> -        S.RRI.IsRetainBlock = Class == IC_RetainBlock;
>> -        // Don't check S.IsKnownIncremented() here because it's not
>> -        // sufficient.
>> -        S.RRI.KnownSafe = S.IsKnownNested();
>> -        S.RRI.Calls.insert(Inst);
>> -      }
>> -
>> -      S.SetAtLeastOneRefCount();
>> -      S.IncrementRefCount();
>> -      S.IncrementNestCount();
>> -      continue;
>> -    }
>> -    case IC_Release: {
>> -      Arg = GetObjCArg(Inst);
>> -
>> -      PtrState &S = MyStates.getPtrTopDownState(Arg);
>> -      S.DecrementRefCount();
>> -      S.DecrementNestCount();
>> -
>> -      switch (S.GetSeq()) {
>> -      case S_Retain:
>> -      case S_CanRelease:
>> -        S.RRI.ReverseInsertPts.clear();
>> -        // FALL THROUGH
>> -      case S_Use:
>> -        S.RRI.ReleaseMetadata = Inst->getMetadata(ImpreciseReleaseMDKind);
>> -        S.RRI.IsTailCallRelease = cast<CallInst>(Inst)->isTailCall();
>> -        Releases[Inst] = S.RRI;
>> -        S.ClearSequenceProgress();
>> -        break;
>> -      case S_None:
>> -        break;
>> -      case S_Stop:
>> -      case S_Release:
>> -      case S_MovableRelease:
>> -        llvm_unreachable("top-down pointer in release state!");
>> -      }
>> -      break;
>> -    }
>> -    case IC_AutoreleasepoolPop:
>> -      // Conservatively, clear MyStates for all known pointers.
>> -      MyStates.clearTopDownPointers();
>> -      continue;
>> -    case IC_AutoreleasepoolPush:
>> -    case IC_None:
>> -      // These are irrelevant.
>> -      continue;
>> -    default:
>> -      break;
>> -    }
>> -
>> -    // Consider any other possible effects of this instruction on each
>> -    // pointer being tracked.
>> -    for (BBState::ptr_iterator MI = MyStates.top_down_ptr_begin(),
>> -         ME = MyStates.top_down_ptr_end(); MI != ME; ++MI) {
>> -      const Value *Ptr = MI->first;
>> -      if (Ptr == Arg)
>> -        continue; // Handled above.
>> -      PtrState &S = MI->second;
>> -      Sequence Seq = S.GetSeq();
>> -
>> -      // Check for possible releases.
>> -      if (CanAlterRefCount(Inst, Ptr, PA, Class)) {
>> -        S.DecrementRefCount();
>> -        switch (Seq) {
>> -        case S_Retain:
>> -          S.SetSeq(S_CanRelease);
>> -          assert(S.RRI.ReverseInsertPts.empty());
>> -          S.RRI.ReverseInsertPts.insert(Inst);
>> -
>> -          // One call can't cause a transition from S_Retain to S_CanRelease
>> -          // and S_CanRelease to S_Use. If we've made the first transition,
>> -          // we're done.
>> -          continue;
>> -        case S_Use:
>> -        case S_CanRelease:
>> -        case S_None:
>> -          break;
>> -        case S_Stop:
>> -        case S_Release:
>> -        case S_MovableRelease:
>> -          llvm_unreachable("top-down pointer in release state!");
>> -        }
>> -      }
>> -
>> -      // Check for possible direct uses.
>> -      switch (Seq) {
>> -      case S_CanRelease:
>> -        if (CanUse(Inst, Ptr, PA, Class))
>> -          S.SetSeq(S_Use);
>> -        break;
>> -      case S_Retain:
>> -      case S_Use:
>> -      case S_None:
>> -        break;
>> -      case S_Stop:
>> -      case S_Release:
>> -      case S_MovableRelease:
>> -        llvm_unreachable("top-down pointer in release state!");
>> -      }
>> -    }
>> +    NestingDetected |= VisitInstructionTopDown(Inst, Releases, MyStates);
>>  }
>> 
>>  CheckForCFGHazards(BB, BBStates, MyStates);
>> 
>> 
>> _______________________________________________
>> 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