LLVM Tablegen is an approach for representation but it still requires the compiler writer to write everything down and then use it effectively and correctly. This is really hard and it doesn't get done. Instead someone ports a backend and then kinda sorta improves things until it seems better than it was.
Intel has a fine compiler which goes further. It sure isn't open source and it costs a few bucks. They're also contributing LLVM now.
The reason don't even try makes sense both for compiler writer and assembly writer is that this stuff is really hard. Also CPUs are damn fast and Intel (and ARM and ...) work really hard to solve problems dynamically (branch prediction, speculation, register renaming, caching, speculation, ...). In fact, you shouldn't even try this unless you know a lot. Agner Fog and Peter Cordes should be familiar names. But if you do know a lot, beating compilers is not difficult at all. Finding the right place to beat them? That's tough.
[1] https://www.intel.com/content/dam/www/public/us/en/documents...
Heh. I had this the other way around - picked up 68k asm for fun long before C/C++, and couldn't understand why people had such difficulty with the concepts in those.
I've never learned x86 - partly because I worry that I'd enjoy it too much and waste oodles of time "optimizing" things that don't need it. Probably useful to be able to at least read it, though.
A few weeks ago I tried my hand at optimizing some code using the vector instructions. While I was able to beat clang quite easily using assembly, I just could not beat GCC. That was sobering. There's probably some 1000 page tome I have to read to understand where I messed up in optimizing.
If you never need to optimise C or C++ code why are you using these languages? Seriously? You've almost certainly got the wrong tool for the job. (Ok sometimes someone has made a legacy decision and you're stuck with it for bad reasons. Meh).
If you don't try to understand it, you won't know things like "Never use a linked list if you care about performance at all." Even Bjarne has twigged to that one (at last!). C and C++ are languages you use when you need performance, understanding the CPU as best you are capable is crucial for performance. DO try. In fact it's insane not to work on your understanding.
Don't even try to justify a statement of "don't even try to understand". It's wrong thinking from top to bottom. Here, as everywhere. No really.
In software, it's likely that latency is not going to be a problem as long as you can get more throughput (you probably don't care if the time between when the program hits your opcode and the CPU actually executes your instruction is 1 nanosecond later than it conceivably could be as long as the number of instructions executed per millisecond is greater).
In any case, yes, you need to expose the same machine code interface, not just so people can write new software using the same code, but so that old code continues to work. It would be a nightmare if every few years there were incompatible changes to the instruction set.
And your last paragraph makes sense for why the same interface.
The other answers on that question make some good points, too.
Most instructions decode to a single internal uop already, so x86 machine code is just a compact way of programming in uops.
Things like variable-count shifts are multi-uop because of x86's legacy CISC flag-handling, but BMI2 fixes that by giving you no-flags shifts that do decode to a single uop.
You're usually not missing out on much.
Also, there's plenty of voodoo besides just translation to uops. Programming in uops directly wouldn't help you figure out why there seems to be some kind of limit on register reads per clock (http://agner.org/optimize/blog/read.php?i=415#852) for example, since the uops you'd program with would still have register renaming done to them as they're issued into the out-of-order core.
One thing to keep in mind is that the CPU is no longer the CPU you think it is. While the x86 instruction set used to directly control the processor, today it's just a compatibility shim. Under the covers, the CPU is converting your assembly into its own microcode and it's that microcode which is doing the real work. For example, look at some of the block diagrams in section 2 of this Intel manual:
https://software.intel.com/sites/default/files/managed/a4/60...
Combine that with all kinds of other voodoo they've added--fancy caches, branch prediction, and so forth--and the "don't even try" maxim starts to make sense. I'd amend that to say "don't even try unless you're just curious."
Personally, I think assembly is a great learning tool, e.g. for understanding how pointers work, how the stack works vs. the heap, how function calls work, and so-forth. I was exposed to Motorola 68K assembly in college and it completely changed my world--lots of C++ things I considered voodoo suddenly made total sense. But I've never used assembly in production code and probably never will.