LLVM: lib/TableGen/StringMatcher.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

17#include

18#include

19#include

20#include

21#include

22

23using namespace llvm;

24

25

26

27

28static unsigned

31 for (auto [Idx, Letter] : enumerate(Matches[0]->first)) {

32

33

35 if (Match->first[Idx] != Letter)

36 return Idx;

37 }

38

39 return Matches[0]->first.size();

40}

41

42

43

44

45

46

47bool StringMatcher::EmitStringMatcherForChar(

49 bool IgnoreDuplicates) const {

50 assert(!Matches.empty() && "Must have at least one string to match!");

51 std::string Indent(IndentCount * 2 + 4, ' ');

52

53

54

55 if (CharNo == Matches[0]->first.size()) {

56 if (Matches.size() > 1 && !IgnoreDuplicates)

58

59

60 StringRef Code = Matches[0]->second;

61

62 std::pair<StringRef, StringRef> Split = Code.split('\n');

63 OS << Indent << Split.first << "\t // \"" << Matches[0]->first << "\"\n";

64

66 while (Code.empty()) {

68 OS << Indent << Split.first << "\n";

70 }

71 return false;

72 }

73

74

75 std::map<char, std::vector<const StringPair*>> MatchesByLetter;

76

77 for (const StringPair *Match : Matches)

78 MatchesByLetter[Match->first[CharNo]].push_back(Match);

79

80

81

82 if (MatchesByLetter.size() == 1) {

84 unsigned NumChars = FirstNonCommonLetter-CharNo;

85

86

87 if (NumChars == 1) {

88

89

90 OS << Indent << "if (" << StrVariableName << "[" << CharNo << "] != '"

91 << Matches[0]->first[CharNo] << "')\n";

92 OS << Indent << " break;\n";

93 } else {

94

95

96 OS << Indent << "if (memcmp(" << StrVariableName << ".data()+" << CharNo

97 << ", \"" << Matches[0]->first.substr(CharNo, NumChars) << "\", "

98 << NumChars << ") != 0)\n";

99 OS << Indent << " break;\n";

100 }

101

102 return EmitStringMatcherForChar(Matches, FirstNonCommonLetter, IndentCount,

103 IgnoreDuplicates);

104 }

105

106

107

108 OS << Indent << "switch (" << StrVariableName << "[" << CharNo << "]) {\n";

109 OS << Indent << "default: break;\n";

110

111 for (const auto &[Letter, Matches] : MatchesByLetter) {

112

113 OS << Indent << "case '" << Letter << "':\t // " << Matches.size()

114 << " string";

115 if (Matches.size() != 1)

116 OS << 's';

117 OS << " to match.\n";

118 if (EmitStringMatcherForChar(Matches, CharNo + 1, IndentCount + 1,

119 IgnoreDuplicates))

120 OS << Indent << " break;\n";

121 }

122

123 OS << Indent << "}\n";

124 return true;

125}

126

127

128

130

131 if (Matches.empty()) return;

132

133

134 std::map<unsigned, std::vector<const StringPair*>> MatchesByLength;

135

136 for (const StringPair &Match : Matches)

137 MatchesByLength[Match.first.size()].push_back(&Match);

138

139

140

141 OS.indent(Indent*2+2) << "switch (" << StrVariableName << ".size()) {\n";

142 OS.indent(Indent*2+2) << "default: break;\n";

143

144 for (const auto &[Length, Matches] : MatchesByLength) {

145 OS.indent(Indent * 2 + 2)

146 << "case " << Length << ":\t // " << Matches.size() << " string"

147 << (Matches.size() == 1 ? "" : "s") << " to match.\n";

148 if (EmitStringMatcherForChar(Matches, 0, Indent, IgnoreDuplicates))

149 OS.indent(Indent*2+4) << "break;\n";

150 }

151

152 OS.indent(Indent*2+2) << "}\n";

153}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static unsigned FindFirstNonCommonLetter(ArrayRef< const StringMatcher::StringPair * > Matches)

FindFirstNonCommonLetter - Find the first character in the keys of the string pairs that is not share...

Definition StringMatcher.cpp:29

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

ArrayRef< T > drop_front(size_t N=1) const

Drop the first N elements of the array.

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

void Emit(unsigned Indent=0, bool IgnoreDuplicates=false) const

Emit - Top level entry point.

Definition StringMatcher.cpp:129

std::pair< std::string, std::string > StringPair

NodeAddr< CodeNode * > Code

This is an optimization pass for GlobalISel generic memory operations.

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)