X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FREADME.txt;h=78dcb12581c699ff3271d73fce612b6d8ca5b386;hb=d24479730a8790d82c4859dc477bc2416d7a6bda;hp=81b0f9cc23a362b11e71da397c607643d5999143;hpb=9cf8ef63c62b0c8865bc4febd45c83e9965b34f2;p=oota-llvm.git diff --git a/lib/Target/README.txt b/lib/Target/README.txt index 81b0f9cc23a..78dcb12581c 100644 --- a/lib/Target/README.txt +++ b/lib/Target/README.txt @@ -1486,3 +1486,206 @@ codegen. 456.hmmer apparently uses strcspn and strspn a lot. 471.omnetpp uses strspn. //===---------------------------------------------------------------------===// + +"gas" uses this idiom: + else if (strchr ("+-/*%|&^:[]()~", *intel_parser.op_string)) +.. + else if (strchr ("<>", *intel_parser.op_string) + +Those should be turned into a switch. + +//===---------------------------------------------------------------------===// + +252.eon contains this interesting code: + + %3072 = getelementptr [100 x i8]* %tempString, i32 0, i32 0 + %3073 = call i8* @strcpy(i8* %3072, i8* %3071) nounwind + %strlen = call i32 @strlen(i8* %3072) ; uses = 1 + %endptr = getelementptr [100 x i8]* %tempString, i32 0, i32 %strlen + call void @llvm.memcpy.i32(i8* %endptr, + i8* getelementptr ([5 x i8]* @"\01LC42", i32 0, i32 0), i32 5, i32 1) + %3074 = call i32 @strlen(i8* %endptr) nounwind readonly + +This is interesting for a couple reasons. First, in this: + + %3073 = call i8* @strcpy(i8* %3072, i8* %3071) nounwind + %strlen = call i32 @strlen(i8* %3072) + +The strlen could be replaced with: %strlen = sub %3072, %3073, because the +strcpy call returns a pointer to the end of the string. Based on that, the +endptr GEP just becomes equal to 3073, which eliminates a strlen call and GEP. + +Second, the memcpy+strlen strlen can be replaced with: + + %3074 = call i32 @strlen([5 x i8]* @"\01LC42") nounwind readonly + +Because the destination was just copied into the specified memory buffer. This, +in turn, can be constant folded to "4". + +In other code, it contains: + + %endptr6978 = bitcast i8* %endptr69 to i32* + store i32 7107374, i32* %endptr6978, align 1 + %3167 = call i32 @strlen(i8* %endptr69) nounwind readonly + +Which could also be constant folded. Whatever is producing this should probably +be fixed to leave this as a memcpy from a string. + +Further, eon also has an interesting partially redundant strlen call: + +bb8: ; preds = %_ZN18eonImageCalculatorC1Ev.exit + %682 = getelementptr i8** %argv, i32 6 ; [#uses=2] + %683 = load i8** %682, align 4 ; [#uses=4] + %684 = load i8* %683, align 1 ; [#uses=1] + %685 = icmp eq i8 %684, 0 ; [#uses=1] + br i1 %685, label %bb10, label %bb9 + +bb9: ; preds = %bb8 + %686 = call i32 @strlen(i8* %683) nounwind readonly + %687 = icmp ugt i32 %686, 254 ; [#uses=1] + br i1 %687, label %bb10, label %bb11 + +bb10: ; preds = %bb9, %bb8 + %688 = call i32 @strlen(i8* %683) nounwind readonly + +This could be eliminated by doing the strlen once in bb8, saving code size and +improving perf on the bb8->9->10 path. + +//===---------------------------------------------------------------------===// + +I see an interesting fully redundant call to strlen left in 186.crafty:InputMove +which looks like: + %movetext11 = getelementptr [128 x i8]* %movetext, i32 0, i32 0 + + +bb62: ; preds = %bb55, %bb53 + %promote.0 = phi i32 [ %169, %bb55 ], [ 0, %bb53 ] + %171 = call i32 @strlen(i8* %movetext11) nounwind readonly align 1 + %172 = add i32 %171, -1 ; [#uses=1] + %173 = getelementptr [128 x i8]* %movetext, i32 0, i32 %172 + +... no stores ... + br i1 %or.cond, label %bb65, label %bb72 + +bb65: ; preds = %bb62 + store i8 0, i8* %173, align 1 + br label %bb72 + +bb72: ; preds = %bb65, %bb62 + %trank.1 = phi i32 [ %176, %bb65 ], [ -1, %bb62 ] + %177 = call i32 @strlen(i8* %movetext11) nounwind readonly align 1 + +Note that on the bb62->bb72 path, that the %177 strlen call is partially +redundant with the %171 call. At worst, we could shove the %177 strlen call +up into the bb65 block moving it out of the bb62->bb72 path. However, note +that bb65 stores to the string, zeroing out the last byte. This means that on +that path the value of %177 is actually just %171-1. A sub is cheaper than a +strlen! + +This pattern repeats several times, basically doing: + + A = strlen(P); + P[A-1] = 0; + B = strlen(P); + where it is "obvious" that B = A-1. + +//===---------------------------------------------------------------------===// + +186.crafty contains this interesting pattern: + +%77 = call i8* @strstr(i8* getelementptr ([6 x i8]* @"\01LC5", i32 0, i32 0), + i8* %30) +%phitmp648 = icmp eq i8* %77, getelementptr ([6 x i8]* @"\01LC5", i32 0, i32 0) +br i1 %phitmp648, label %bb70, label %bb76 + +bb70: ; preds = %OptionMatch.exit91, %bb69 + %78 = call i32 @strlen(i8* %30) nounwind readonly align 1 ; [#uses=1] + +This is basically: + cststr = "abcdef"; + if (strstr(cststr, P) == cststr) { + x = strlen(P); + ... + +The strstr call would be significantly cheaper written as: + +cststr = "abcdef"; +if (memcmp(P, str, strlen(P))) + x = strlen(P); + +This is memcmp+strlen instead of strstr. This also makes the strlen fully +redundant. + +//===---------------------------------------------------------------------===// + +186.crafty also contains this code: + +%1906 = call i32 @strlen(i8* getelementptr ([32 x i8]* @pgn_event, i32 0,i32 0)) +%1907 = getelementptr [32 x i8]* @pgn_event, i32 0, i32 %1906 +%1908 = call i8* @strcpy(i8* %1907, i8* %1905) nounwind align 1 +%1909 = call i32 @strlen(i8* getelementptr ([32 x i8]* @pgn_event, i32 0,i32 0)) +%1910 = getelementptr [32 x i8]* @pgn_event, i32 0, i32 %1909 + +The last strlen is computable as 1908-@pgn_event, which means 1910=1908. + +//===---------------------------------------------------------------------===// + +186.crafty has this interesting pattern with the "out.4543" variable: + +call void @llvm.memcpy.i32( + i8* getelementptr ([10 x i8]* @out.4543, i32 0, i32 0), + i8* getelementptr ([7 x i8]* @"\01LC28700", i32 0, i32 0), i32 7, i32 1) +%101 = call@printf(i8* ... @out.4543, i32 0, i32 0)) nounwind + +It is basically doing: + + memcpy(globalarray, "string"); + printf(..., globalarray); + +Anyway, by knowing that printf just reads the memory and forward substituting +the string directly into the printf, this eliminates reads from globalarray. +Since this pattern occurs frequently in crafty (due to the "DisplayTime" and +other similar functions) there are many stores to "out". Once all the printfs +stop using "out", all that is left is the memcpy's into it. This should allow +globalopt to remove the "stored only" global. + +//===---------------------------------------------------------------------===// + +This code: + +define inreg i32 @foo(i8* inreg %p) nounwind { + %tmp0 = load i8* %p + %tmp1 = ashr i8 %tmp0, 5 + %tmp2 = sext i8 %tmp1 to i32 + ret i32 %tmp2 +} + +could be dagcombine'd to a sign-extending load with a shift. +For example, on x86 this currently gets this: + + movb (%eax), %al + sarb $5, %al + movsbl %al, %eax + +while it could get this: + + movsbl (%eax), %eax + sarl $5, %eax + +//===---------------------------------------------------------------------===// + +GCC PR31029: + +int test(int x) { return 1-x == x; } // --> return false +int test2(int x) { return 2-x == x; } // --> return x == 1 ? + +Always foldable for odd constants, what is the rule for even? + +//===---------------------------------------------------------------------===// + +PR 3381: GEP to field of size 0 inside a struct could be turned into GEP +for next field in struct (which is at same address). + +For example: store of float into { {{}}, float } could be turned into a store to +the float directly. +