Go to the documentation of this file.
38 #include <sys/types.h>
50 #include "llvm/Config/config.h"
59 {
"alnum",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
61 {
"alpha",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
63 {
"blank",
" \t",
""} ,
64 {
"cntrl",
"\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
65 \25\26\27\30\31\32\33\34\35\36\37\177",
""} ,
66 {
"digit",
"0123456789",
""} ,
67 {
"graph",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
68 0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
70 {
"lower",
"abcdefghijklmnopqrstuvwxyz",
72 {
"print",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
73 0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
75 {
"punct",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
77 {
"space",
"\t\n\v\f\r ",
""} ,
78 {
"upper",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
80 {
"xdigit",
"0123456789ABCDEFabcdef",
100 {
"backspace",
'\b' },
106 {
"vertical-tab",
'\v' },
108 {
"form-feed",
'\f' },
110 {
"carriage-return",
'\r' },
134 {
"exclamation-mark",
'!' },
135 {
"quotation-mark",
'"' },
136 {
"number-sign",
'#' },
137 {
"dollar-sign",
'$' },
138 {
"percent-sign",
'%' },
139 {
"ampersand",
'&' },
140 {
"apostrophe",
'\'' },
141 {
"left-parenthesis",
'(' },
142 {
"right-parenthesis",
')' },
144 {
"plus-sign",
'+' },
147 {
"hyphen-minus",
'-' },
149 {
"full-stop",
'.' },
163 {
"semicolon",
';' },
164 {
"less-than-sign",
'<' },
165 {
"equals-sign",
'=' },
166 {
"greater-than-sign",
'>' },
167 {
"question-mark",
'?' },
168 {
"commercial-at",
'@' },
169 {
"left-square-bracket",
'[' },
170 {
"backslash",
'\\' },
171 {
"reverse-solidus",
'\\' },
172 {
"right-square-bracket",
']' },
173 {
"circumflex",
'^' },
174 {
"circumflex-accent",
'^' },
175 {
"underscore",
'_' },
177 {
"grave-accent",
'`' },
178 {
"left-brace",
'{' },
179 {
"left-curly-bracket",
'{' },
180 {
"vertical-line",
'|' },
181 {
"right-brace",
'}' },
182 {
"right-curly-bracket",
'}' },
250 #define PEEK() (*p->next)
251 #define PEEK2() (*(p->next+1))
252 #define MORE() (p->end - p->next > 0)
253 #define MORE2() (p->end - p->next > 1)
254 #define SEE(c) (MORE() && PEEK() == (c))
255 #define SEETWO(a, b) (MORE2() && PEEK() == (a) && PEEK2() == (b))
256 #define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0)
257 #define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
258 #define NEXT() (p->next++)
259 #define NEXT2() (p->next += 2)
260 #define NEXTn(n) (p->next += (n))
261 #define GETNEXT() (*p->next++)
262 #define SETERROR(e) seterr(p, (e))
263 #define REQUIRE(co, e) (void)((co) || SETERROR(e))
264 #define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e))
265 #define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e))
266 #define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e))
267 #define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
268 #define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
269 #define AHEAD(pos) dofwd(p, pos, HERE()-(pos))
270 #define ASTERN(sop, pos) EMIT(sop, HERE()-pos)
271 #define HERE() (p->slen)
272 #define THERE() (p->slen - 1)
273 #define THERETHERE() (p->slen - 2)
274 #define DROP(n) (p->slen -= (n))
276 #ifdef _POSIX2_RE_DUP_MAX
277 #define DUPMAX _POSIX2_RE_DUP_MAX
281 #define INFINITY (DUPMAX + 1)
284 static int never = 0;
301 # define GOODFLAGS(f) (f)
303 # define GOODFLAGS(f) ((f)&~REG_DUMP)
315 len = strlen((
const char *)pattern);
323 p->strip = (
sop *)calloc(
p->ssize,
sizeof(
sop));
325 if (
p->strip == NULL) {
332 p->next = (
char *)pattern;
333 p->end =
p->next + len;
352 g->categories = &
g->catspace[-(CHAR_MIN)];
353 (void) memset((
char *)
g->catspace, 0,
NC*
sizeof(
cat_t));
404 while (
MORE() && (
c =
PEEK()) !=
'|' &&
c != stop)
456 p->pbegin[subno] =
HERE();
461 p->pend[subno] =
HERE();
467 #ifndef POSIX_MISTAKE
510 if (
c >=
'1' &&
c <=
'9') {
516 backrefnum =
c -
'0';
517 if (
p->pend[backrefnum] == 0) {
525 assert(backrefnum <= p->
g->nsub);
527 assert(
p->pbegin[backrefnum] != 0);
530 (void)
dupl(
p,
p->pbegin[backrefnum]+1,
p->pend[backrefnum]);
551 if (!(
c ==
'*' ||
c ==
'+' ||
c ==
'?' ||
601 if (!(
c ==
'*' ||
c ==
'+' ||
c ==
'?' ||
669 # define BACKSL (1<<CHAR_BIT)
696 p->pbegin[subno] =
HERE();
702 p->pend[subno] =
HERE();
723 if (
p->pend[
i] != 0) {
729 (void)
dupl(
p,
p->pbegin[
i]+1,
p->pend[
i]);
749 }
else if (
EATTWO(
'\\',
'{')) {
803 if (
p->end -
p->next > 5) {
804 if (strncmp(
p->next,
"[:<:]]", 6) == 0) {
809 if (strncmp(
p->next,
"[:>:]]", 6) == 0) {
842 for (
i =
p->g->csetsize - 1;
i >= 0;
i--)
843 if (
CHIN(cs,
i) && isalpha(
i)) {
854 for (
i =
p->g->csetsize - 1;
i >= 0;
i--)
867 if (
nch(
p, cs) == 1) {
931 for (
i = start;
i <= finish;
i++)
953 if (strncmp(cp->
name,
sp, len) == 0 && cp->
name[len] ==
'\0')
955 if (cp->
name == NULL) {
962 while ((
c = *u++) !=
'\0')
964 for (u = cp->
multis; *u !=
'\0'; u += strlen(u) + 1)
1019 if (strncmp(cp->
name,
sp, len) == 0 && strlen(cp->
name) == len)
1036 return ((
uch)tolower(ch));
1037 else if (islower(ch))
1038 return ((
uch)toupper(ch));
1051 char *oldnext =
p->next;
1052 char *oldend =
p->end;
1074 cat_t *cap =
p->g->categories;
1081 cap[ch] =
p->g->ncategories++;
1093 char *oldnext =
p->next;
1094 char *oldend =
p->end;
1121 # define REP(f, t) ((f)*8 + (t))
1122 # define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
1198 int no =
p->g->ncsets++;
1202 size_t css = (
size_t)
p->g->csetsize;
1205 if (no >=
p->ncsalloc) {
1208 p->ncsalloc += CHAR_BIT;
1210 if (nc > SIZE_MAX /
sizeof(
cset))
1212 assert(nc % CHAR_BIT == 0);
1213 nbytes = nc / CHAR_BIT * css;
1215 ptr = (
cset *)realloc((
char *)
p->g->sets, nc *
sizeof(
cset));
1220 ptr = (
uch *)realloc((
char *)
p->g->setbits, nbytes);
1223 p->g->setbits = ptr;
1225 for (
i = 0;
i < no;
i++)
1226 p->g->sets[
i].ptr =
p->g->setbits + css*(
i/CHAR_BIT);
1228 (void) memset((
char *)
p->g->setbits + (nbytes - css), 0, css);
1231 if (
p->g->sets == NULL ||
p->g->setbits == NULL)
1234 cs = &
p->g->sets[no];
1235 cs->
ptr =
p->g->setbits + css*((no)/CHAR_BIT);
1236 cs->
mask = 1 << ((no) % CHAR_BIT);
1245 free(
p->g->setbits);
1246 p->g->setbits = NULL;
1260 cset *top = &
p->g->sets[
p->g->ncsets];
1261 size_t css = (
size_t)
p->g->csetsize;
1263 for (
i = 0;
i < css;
i++)
1283 cset *top = &
p->g->sets[
p->g->ncsets];
1285 size_t css = (
size_t)
p->g->csetsize;
1288 for (cs2 = &
p->g->sets[0]; cs2 < top; cs2++)
1289 if (cs2->
hash ==
h && cs2 != cs) {
1291 for (
i = 0;
i < css;
i++)
1303 return((
int)(cs -
p->g->sets));
1313 size_t css = (
size_t)
p->g->csetsize;
1315 for (
i = 0;
i < css;
i++)
1329 size_t css = (
size_t)
p->g->csetsize;
1332 for (
i = 0;
i < css;
i++)
1347 cs->
smultis += strlen(cp) + 1;
1395 int ncols = (
g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
1396 unsigned uc = (
uch)
c;
1398 for (
i = 0, col =
g->setbits; i < ncols; i++, col += g->csetsize)
1412 int ncols = (
g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
1413 unsigned uc1 = (
uch)c1;
1414 unsigned uc2 = (
uch)
c2;
1416 for (
i = 0, col =
g->setbits; i < ncols; i++, col += g->csetsize)
1417 if (col[uc1] != col[uc2])
1428 cat_t *cats =
g->categories;
1437 for (
c = CHAR_MIN;
c <= CHAR_MAX;
c++)
1439 cat =
g->ncategories++;
1441 for (
c2 =
c+1;
c2 <= CHAR_MAX;
c2++)
1456 sopno len = finish - start;
1463 (void) memmove((
char *)(
p->strip +
p->slen),
1464 (
char *)(
p->strip + start), (
size_t)len*
sizeof(
sop));
1487 if (
p->slen >=
p->ssize)
1492 p->strip[
p->slen++] =
SOP(
op, opnd);
1517 if (
p->pbegin[
i] >= pos) {
1520 if (
p->pend[
i] >= pos) {
1525 memmove((
char *)&
p->strip[pos+1], (
char *)&
p->strip[pos],
1541 p->strip[pos] =
OP(
p->strip[pos]) | value;
1552 if (
p->ssize >=
size)
1555 if ((uintptr_t)
size > SIZE_MAX /
sizeof(
sop)) {
1575 g->nstates =
p->slen;
1576 if ((uintptr_t)
p->slen > SIZE_MAX /
sizeof(
sop)) {
1577 g->strip =
p->strip;
1582 g->strip = (
sop *)realloc((
char *)
p->strip,
p->slen *
sizeof(
sop));
1583 if (
g->strip == NULL) {
1585 g->strip =
p->strip;
1615 scan =
g->strip + 1;
1621 newstart =
scan - 1;
1643 if (newlen >
g->mlen) {
1656 g->must = malloc((
size_t)
g->mlen + 1);
1657 if (
g->must == NULL) {
1663 for (
i =
g->mlen;
i > 0;
i--) {
1666 assert(cp < g->must +
g->mlen);
1667 *cp++ = (char)
OPND(
s);
1687 scan =
g->strip + 1;
1695 if (plusnest > maxnest)
static int freezeset(struct parse *, cset *)
static Expected< BitVector > scan(StringRef &S, StringRef Original)
static void mccase(struct parse *, cset *)
static void p_b_term(struct parse *, cset *)
static void nonnewline(struct parse *)
static struct cclass cclasses[]
This might compile to this xmm1 xorps xmm0 movss xmm0 ret Now consider if the code caused xmm1 to get spilled This might produce this xmm1 movaps c2(%esp) ... xorps %xmm0
static void categorize(struct parse *, struct re_guts *)
static void mcinvert(struct parse *, cset *)
static int p_simp_re(struct parse *, int)
static int firstch(struct parse *, cset *)
static cset * allocset(struct parse *)
static int seterr(struct parse *, int)
static int samesets(struct re_guts *, int, int)
static void stripsnug(struct parse *, struct re_guts *)
static void findmust(struct parse *, struct re_guts *)
to esp esp setne al movzbw ax esp setg cl movzbw cx cmove cx cl jne LBB1_2 esp ret(also really horrible code on ppc). This is due to the expand code for 64-bit compares. GCC produces multiple branches
int llvm_regcomp(llvm_regex_t *preg, const char *pattern, int cflags)
static void doemit(struct parse *, sop, size_t)
should just be implemented with a CLZ instruction Since there are other e g
the resulting code requires compare and branches when and if * p
static int nch(struct parse *, cset *)
static void dofwd(struct parse *, sopno, sop)
static void bothcases(struct parse *, int)
static void p_ere(struct parse *, int)
static void enlarge(struct parse *, sopno)
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int c
size_t llvm_strlcpy(char *dst, const char *src, size_t siz)
static struct cname cnames[]
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
void llvm_regfree(llvm_regex_t *)
multiplies can be turned into SHL s
static void p_b_cclass(struct parse *, cset *)
static void mcadd(struct parse *, cset *, const char *)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void doinsert(struct parse *, sop, size_t, sopno)
if(llvm_vc STREQUAL "") set(fake_version_inc "$
static int p_count(struct parse *)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
this could be done in SelectionDAGISel along with other special for
static void freeset(struct parse *, cset *)
static void p_bracket(struct parse *)
static char p_b_symbol(struct parse *)
static void p_b_eclass(struct parse *, cset *)
static void ordinary(struct parse *, int)
static void p_bre(struct parse *, int, int)
static char othercase(int)
static char p_b_coll_elem(struct parse *, int)
static void p_str(struct parse *)
static sopno dupl(struct parse *, sopno, sopno)
static void repeat(struct parse *, sopno, int, int)
the multiplication has a latency of four as opposed to two cycles for the movl lea variant It appears gcc place string data with linkonce linkage in section coalesced instead of section coalesced Take a look at darwin h
static sopno pluscount(struct parse *, struct re_guts *)
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
static void p_ere_exp(struct parse *)
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
static int isinsets(struct re_guts *, int)