https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68991

--- Comment #7 from H.J. Lu <hjl.tools at gmail dot com> ---
[hjl@gnu-tools-1 pr68991]$ cat x.cc
#include <bitset>
#include <string>

typedef std::string StringRef;

template<typename T>
class ArrayRef {
public:
    typedef const T *iterator;
    typedef size_t size_type;

private:
    const T *Data;
    size_type Length;

public:
    iterator begin() const { return Data; }
    iterator end() const { return Data + Length; }
};

const unsigned MAX_SUBTARGET_FEATURES = 128;
class FeatureBitset : public std::bitset<MAX_SUBTARGET_FEATURES> {
public:

    FeatureBitset() : bitset() {}
    FeatureBitset(const bitset<MAX_SUBTARGET_FEATURES>& B) : bitset(B) {}
};

struct SubtargetFeatureKV {
  const char *Key;
  FeatureBitset Value;
  FeatureBitset Implies;
  bool operator<(StringRef S) const;
};

struct SubtargetInfoKV {
  const char *Key;
  const void *Value;
};
class SubtargetFeatures {
public:
    FeatureBitset ToggleFeature(FeatureBitset Bits, StringRef String,
                                ArrayRef<SubtargetFeatureKV> FeatureTable);
};

static inline bool hasFlag(StringRef Feature) {
  char Ch = Feature[0];
  return Ch == '+' || Ch =='-';
}

static inline std::string StripFlag(StringRef Feature) {
  return Feature;
}

static const SubtargetFeatureKV *Find(StringRef S,
                                      ArrayRef<SubtargetFeatureKV> A) {
  auto F = std::lower_bound(A.begin(), A.end(), S);
  return F;
}

static
void ClearImpliedBits(FeatureBitset &Bits,
                      const SubtargetFeatureKV *FeatureEntry,
                      ArrayRef<SubtargetFeatureKV> FeatureTable) {
  for (auto &FE : FeatureTable) {
    if (FeatureEntry->Value == FE.Value) continue;

    if ((FE.Implies & FeatureEntry->Value).any()) {
      Bits &= ~FE.Value;
      ClearImpliedBits(Bits, &FE, FeatureTable);
    }
  }
}

FeatureBitset
SubtargetFeatures::ToggleFeature(FeatureBitset Bits, StringRef Feature,
                                 ArrayRef<SubtargetFeatureKV> FeatureTable) {
  const SubtargetFeatureKV *FeatureEntry =
    Find(StripFlag(Feature), FeatureTable);
  if (FeatureEntry) {
    if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) {
      Bits &= ~FeatureEntry->Value;
      ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
    }
  }
  return Bits;
}
[hjl@gnu-tools-1 pr68991]$ gcc -O3 -S x.cc -std=c++11  -mx32 -da 

LRA turns

(insn 364 363 575 49 (set (reg:V4SI 288 [ vect__46.140 ])
        (xor:V4SI (reg:V4SI 289) 
            (subreg:V4SI (reg:TI 287 [ MEM[(const struct bitset &)A_56 + 4] ])
0))) /usr/include/c++/5.3.1/bitset:163 3433 {*xorv4si3}
     (expr_list:REG_DEAD (reg:V4SI 289) 
        (expr_list:REG_DEAD (reg:TI 287 [ MEM[(const struct bitset &)A_56 + 4]
])
            (nil))))

into

(insn 364 363 575 49 (set (reg:V4SI 21 xmm0 [orig:288 vect__46.140 ] [288])
        (xor:V4SI (reg:V4SI 21 xmm0 [289])
            (mem:V4SI (plus:SI (reg/f:SI 44 r15 [orig:118 A ] [118])
                    (const_int 4 [0x4])) [9 MEM[(const struct bitset &)A_56 +
4]+0 S16 A32]))) /usr/include/c++/5.3.1/bitset:163 3433 {*xorv4si3}
     (nil))

Reply via email to